13
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

un-T factory! XAAdvent Calendar 2024

Day 3

【Swiper v11】サムネイルが centeredSlides で常に中央にならなくて詰まった話

Last updated at Posted at 2024-12-03

はじめに

スライドショーが手軽に実装できる JavaScript ライブラリの Swiper.js ですが、カスタマイズに苦労することも多いですよね。
私自身、解決策を探す中で参考サイトが古いバージョンの情報しかなかったり、GitHub の Issue を調べても解決策が見つからなかったりと行き詰まりました。そんな中、試行錯誤を繰り返しながら「こうすればいける!」という方法に辿り着いたのでこの記事で共有したいと思います。

今回ご紹介する方法が必ずしも正攻法ではないかもしれませんが、同じ悩みを抱える方の参考になれば幸いです。

この記事では Swiper バージョン 11.0.5(2024年12月現在)を使用しています。

今回作りたいもの

以下のようなスライダーを作成します。

  • メインのスライダ(上部)とサムネイルのスライダ(下部)が連動する
  • サムネイルは5枚のスライダを表示
  • サムネイルのアクティブスライダは常に中央
  • スライダはループする

img_01.png
右矢印ボタンを押すと、メインのスライドとサムネイルが連動して動く。

いざ、実装!

Swiper の thumbs モジュールを使用し、2つの Swiper を連動させてみます。

thumbs についてはこちら

demo

See the Pen Swiper-demo01 by Miri Inoue (@miri-inoue) on CodePen.

コード

HTML
<div class="swiper-container">
// メインのスライダ
  <div class="swiper main-swiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide01" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide02" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide03" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide04" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide05" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=Slide06" alt=""></div>
    </div>
  </div>
  // サムネイルのスライダ
  <div class="swiper thumbs-swiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=01" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=02" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=03" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=04" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=05" alt=""></div>
      <div class="swiper-slide"><img src="https://placehold.jp/dedede/595959/600x300.png?text=06" alt=""></div>
    </div>
  </div>
  <div class="swiper-button-container">
    <button class="swiper-button-prev" type="button"></button>
    <button class="swiper-button-next" type="button"></button>
  </div>
</div>
CSS
.swiper-container {
  position: relative;
  margin: 0 auto;
  width: 600px;
  height: auto;
}

.swiper-slide {
  img {
    width: 100%;
    height: auto;
  }
}

.swiper-button-prev,
.swiper-button-next {
  position: absolute;
  top: initial;
  bottom: 25px;
}

.thumbs-swiper {
  width: 600px;
}

.swiper-slide-thumb-active {
  border: 5px solid red;
}
JavaScript
const swiper = () => {
// サムネイルにあたるスライダを先に記述します
  const thumbsSwiper = new Swiper(".thumbs-swiper", {
    centeredSlides: true,
    loop: true,
    slidesPerView: 5,
    spaceBetween: 10
  });
  const mainSwiper = new Swiper(".main-swiper", {
    slidesPerView: 1,
    loop: true,
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev"
    },
    thumbs: {
      swiper: thumbsSwiper
    }
  });
};

swiper();

発生した問題

  • アクティブなサムネイルは最初だけ中央で表示されるが、常にセンターにはなってくれない😭
  • サムネイルの表示枚数が 途中で 5枚→4枚 と変化してしまう😭

どうやって解決したか?

メインのスライダを thumbs とすることで、「サムネイルのアクティブスライドを常に中央 × ループ」を再現することができました!

正攻法ではないので実装する場合には注意が必要です。

demo

See the Pen Swiper-demo02 by Miri Inoue (@miri-inoue) on CodePen.

具体的にどういうこと🧐?

img_02.png

メインのスライダとサムネイルのスライダを入れ替え、メインスライダを thumbs として設定しました。

コード

JavaScript
const swiper = () => {
  // thumbsSwiper -> mainSwiper に入れ替え
  const mainSwiper = new Swiper(".main-swiper", {
    loop: true,
    allowTouchMove: false
  });
  //  mainSwiper -> thumbsSwiper に入れ替え
  const thumbsSwiper = new Swiper(".thumbs-swiper", {
    centeredSlides: true,
    slidesPerView: 5,
    spaceBetween: 10,
    loop: true,
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev"
    },
    // thumbs に メインのスライダ
    thumbs: {
      swiper: mainSwiper
    }
  });
};

swiper();

メインスライダを thumbs にする際の注意点

期待する動きになったものの、デメリットや制約があるため実装する際には以下の項目に注意してください。

メインのスライダが1枚のときのみに有効

メインのスライドに centeredSlides: true を設定しても、アクティブなスライドはサムネイルと連動して常に中央になってくれません。

メインのスライドをスワイプしても、サムネイルは連動しない

thumbs に設定したメインのスライドを左右にスワイプしても、メインのスライドは切り替わりますがサムネイルのスライダは連動して動きません。そのため、メインのスライダに allowTouchMove: false を設定し、スライドの動作を 「navigation button のクリック」と 「サムネイルスライダのスワイプ」に絞る必要があります。

アクセシビリティが担保できるか検証が必要

今回の実装では、通常サムネイルスライダを設定する部分にメインのスライダを thumbs として設定しています。そのため、キーボード操作やスクリーンリーダーの読み上げが意図通りにならないといったアクセシビリティの懸念が生じる可能性があります。

  • キーボード操作で全てのスライドが正しく操作できること
  • スクリーンリーダーでメインコンテンツとナビゲーションが適切に認識されること

上記を満たした上で実装を行ってください。

試したこと・検討したこと

CSS のカスタマイズ

サムネイルスライダを

  • overflow: visible
  • slidesPerView: "auto"
  • centeredSlides: false

にし、

その外側の div に

  • width: (( サムネイル1枚分の width + spaceBetween ) * サムネイルを表示したい枚数)
  • overflow: hidden

を設定しました。

アクティブなスライダが常に中央に表示されるものの、

  • サムネイルの表示枚数が 3枚 → 4枚 → 5枚 になる
  • サムネイルが連続して loop せず、右端から左端へ移動するような挙動になる

と、今回期待する挙動になりませんでした。

demo

See the Pen Swiper-demo-css by Miri Inoue (@miri-inoue) on CodePen.

controller モジュールを使用して2つの Swiper を連動

  • loop: true
  • centeredSlides: true
  • サムネイルが slidesPerView: 1

の場合や

  • loop: false
  • centeredSlides: true
  • サムネイルが slidesPerView: 5

の場合問題なく連動しますが、loop × centeredSlides × slidesPerView を掛け合わせるとうまく連動しなくなってしまいます。

demo

See the Pen Swiper-demo-controller by Miri Inoue (@miri-inoue) on CodePen.

Slick

2017年に v1.8.0 がリリースされて以降、長らく更新されていないため選択肢から外しました。(2024年12月時点)

さいごに

Swiper は手軽なライブラリではありますが、今回の経験を通して複雑な実装の場合は 公式のAPI を使用していても特定の組み合わせで期待通りの動きにならなかったり、挙動が不安定になったりとなかなか一筋縄ではいかないことを実感しました。

今回の記事で紹介した方法は正攻法とは言えないので注意が必要ですが、同じような課題に直面している方にとってヒントになれば嬉しいです!

もしこの記事が役立ったり、もっと良い方法や改善案があれば、ぜひコメントなどで共有していただけると嬉しいです!一緒により良い実装を目指していきましょう。

13
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?