【javascript】イメージギャラリーにページネーションを実装する
以下のような、イメージギャラリーを作ってみました。 ページネーションを実装し、9枚ずつ表示されるようにしてあります。 また、クリックすると拡大表示されるlightboxも実装してあります。
HTML
id="imgList"にjavascriptで画像を表示するHTMLを生成。
id="pagination"にjavascriptでページネーションのHTMLを生成。
<div class="content-wrapper">
<!-- 画像が表示される場所 -->
<div class="imgList" id="imgList"></div>
<div class="pagenumbers" id="pagination">
<!-- ページネーションが表示される場所 -->
<ul></ul>
</div>
</div>
CSS
必要な所だけpick up
/* 画像が9枚表示される要素 */
.content-wrapper .imgList {
display: flex;
flex-wrap: wrap;
}
.content-wrapper .imgList .item {
/* 画像の中央寄せ */
display: flex;
justify-content: center;
align-items: center;
/* ホバーした時、画像が拡大してもはみ出した部分を非表示 */
overflow: hidden;
}
.content-wrapper .imgList .item img:hover {
/* ホバーした時、画像が拡大 */
transform: scale(1.2);
}
/* ページネーション */
#pagination ul {
width: 100%;
display: flex;
background: #fff;
padding: 8px;
border-radius: 20px;
}
#pagination ul li {
color: blue;
list-style: none;
line-height: 45px;
text-align: center;
font-size: 18px;
font-weight: 500;
cursor: pointer;
user-select: none;
transition: all 0.3s ease;
}
/* ページ番号のボタン */
#pagination ul li.numb {
list-style: none;
height: 45px;
width: 45px;
margin: 0 3px;
line-height: 45px;
border-radius: 50%;
}
/* …の部分 */
#pagination ul li.dots {
font-size: 22px;
cursor: default;
}
/* ホバーした時、表示されているページの時 */
#pagination li.active,
#pagination ul li.numb:hover,
#pagination ul li:first-child:hover,
#pagination ul li:last-child:hover {
color: #fff;
background: blue;
}
javascript
data.js
配列のlist_itemsに画像のURLを書きます。
const list_items = [
"https://gxy-life.com/images/blog/202112/1.jpeg",
"https://gxy-life.com/images/blog/202112/2 (2).JPG",
"https://gxy-life.com/images/blog/202112/2 (3).JPG",
"https://gxy-life.com/images/blog/202112/2 (4).JPG",
"https://gxy-life.com/images/blog/202112/3.jpg",
"https://gxy-life.com/images/blog/202112/4.jpg",
]
画像が表示される部分のHTML生成
// 画像が表示される要素を取得
const list_element = document.getElementById("imgList");
// 現在のページ数
let current_page = 1;
// 1ページに表示される画像の数
let rows = 9;
// 引数1:画像のURLの配列 2:画像が表示される要素 3:1ページに表示される画像の数 4:現在のページ
function DisplayList(items, wrapper, rows_per_page, page) {
wrapper.innerHTML = "";
page--;
// そのページに表示される画像を計算
let start = rows_per_page * page; // 1ページ目なら0
let end = start + rows_per_page; // 1ページ目なら最後は9
let paginatedItems = items.slice(start, end); // 配列から取り出す
for (let i = 0; i < paginatedItems.length; i++) {
let item = paginatedItems[i];
// HTML生成
let item_element = document.createElement("div");
let img = document.createElement("img");
let a = document.createElement("a");
item_element.classList.add("item");
// lightbox要の属性
a.setAttribute("data-lightbox", "abc");
a.href = item;
img.src = item;
wrapper.appendChild(item_element);
item_element.appendChild(a);
a.appendChild(img);
}
}
ページネーション部分のHTML生成
// トータルページを計算
let totalPageNum = Math.ceil(list_items.length / rows);
function SetupPagination(wrapper, current_page) {
wrapper.innerHTML = "";
let liTag = "";
let active;
let beforePage = current_page - 1;
let afterPage = current_page + 1;
if (current_page > 1) {
// Prevボタン 1ページ目は表示させない
liTag += `<li class="btn prev" onclick="isClicked(${
current_page - 1
})"><span><i class="fas fa-angle-left"></i> Prev</span></li>`;
}
if (current_page > 2) {
// 1ページ目へのリンクボタン
liTag += `<li class="first numb" onclick="isClicked(1)"><span>1</span></li>`;
if (current_page > 3) {
// 4ページ目以降、1ページ目のリンクボタンと1ページ戻るボタンの間の“...”
liTag += `<li class="dots"><span>...</span></li>`;
}
}
if (current_page == totalPageNum) { // 最終ページの時
beforePage = beforePage - 2; //
} else if (current_page == totalPageNum - 1) { // 最終ページの1ページ前の時
beforePage = beforePage - 1;
}
if (current_page == 1) { // 1ページ目の時
afterPage = afterPage + 2;
} else if (current_page == 2) { // 2ページ目の時
afterPage = afterPage + 1;
}
for (var pageNum = beforePage; pageNum <= afterPage; pageNum++) {
if (pageNum > totalPageNum) {
// ページがトータルページを越えた時、処理をスキップ
continue;
}
if (pageNum == 0) {
pageNum = pageNum + 1;
}
if (current_page == pageNum) {
// 選択したページにactiveのクラスを追加
active = "active";
} else {
// その他のページにはactiveを追加しない
active = "";
}
liTag += `<li class="numb ${active}" onclick="isClicked(${pageNum})"><span>${pageNum}</span></li>`;
}
if (current_page < totalPageNum - 1) {
if (current_page < totalPageNum - 2) {
// 最終ページのリンクボタンと1ページ進むボタンの間の“...”
liTag += `<li class="dots"><span>...</span></li>`;
}
// 最終ページのリンクボタン
liTag += `<li class="last numb" onclick="isClicked(${totalPageNum})"><span>${totalPageNum}</span></li>`;
}
if (current_page < totalPageNum) {
// Nextボタン 最終ページでは表示させない
liTag += `<li class="btn next" onclick="isClicked(${
current_page + 1
})"><span>Next <i class="fas fa-angle-right"></i></span></li>`;
}
wrapper.innerHTML = liTag;
}
レスポンシブ対応
レスポンシブに対応できるよう画像のサイズを毎回計算します。
横幅を取得し、三枚ずつなので3で割ります。
画像のアスペクト比は3:2にしたいので、横幅/3*2
function setImgSize() {
const box = document.querySelectorAll(".content-wrapper .imgList .item");
box.forEach((e) => {
let w = Math.floor(list_element.clientWidth / 3);
e.style.width = `${w}px`;
e.style.height = `${(w / 3) * 2}px`;
});
}
クリック処理
クリックした時、先ほどの関数3つを処理します。
function isClicked(e) {
// 画像を表示
DisplayList(list_items, list_element, rows, e);
// パージネーション
SetupPagination(pagination_element, e);
// 画像サイズを計算
setImgSize();
}
lightboxの使い方
lightboxの使い方は以下を参考にしてください。