▲TOPへ戻る

【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`;
    });
  }
js
【javascript】バッククォート内のドルマークの使い方 ` ${ } `

クリック処理

クリックした時、先ほどの関数3つを処理します。

  function isClicked(e) {
    // 画像を表示
    DisplayList(list_items, list_element, rows, e);
    // パージネーション
    SetupPagination(pagination_element, e);
    // 画像サイズを計算
    setImgSize();
  }

lightboxの使い方

lightboxの使い方は以下を参考にしてください。

js
画像を拡大するLightboxの使い方。2ステップだけ

profile

パソコン好きなガオ

コロナ禍によるステイホームを機にプログラミングを学ぶ。パソコンに関してはプロではないが、ちょっと詳しい程度。

パソコン

javascript

カメラ

ブログ