
汎用性に優れている、超定番のjQueryベースのスライダーライブラリといえば、「slick」、「bxSlider」、「FlexSlider」 あたりでしょうか。
しかし、これらの名だたるライブラリよりも、総合的に機能が豊富でカスタマイズ性にも富み、しかもjQueryに依存しないJavaScriptスライダーライブラリとして人気を集めているのが、「Swiper.js」です。
試してみたところ、モバイルデバイスとレスポンシブ表示にも対応しているだけでなく、パラメータが豊富で非常に凝ったスライドショーでもあまりに簡単に実装できる優れものだったので、いくつかのサンプルと共にご紹介します。
INDEX
Swiper.js の基本的な使い方
Swiper.js を使用するには、headセクション内にCSSと、</body>の前にメインのJavaScriptファイルを読み込んでおきます。
ライブラリ自体をダウンロードするか、CDN経由でも利用できます。
.swiper-container) が .swiper に変更されています。バージョン6以前からアップデートする場合は、CSS と JavaScript 内で.swiper-containerと指定している箇所をすべて.swiperに置換する必要があります。ライブラリの読み込み
CSS
<head> ... <link rel="stylesheet" href="path/to/swiper-bundle.min.css" /> <!-- CDNの場合 --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/7.3.3/swiper-bundle.min.css" /> </head>
JavaScript
<body> ... <script src="path/to/swiper-bundle.min.js"></script> <!-- CDNの場合 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/7.3.3/swiper-bundle.min.js"></script> </body>
スライダーのHTML
基本となるHTML構成は、以下のようにします。
<!-- スライダー全体を括るメインコンテナ -->
<div class="swiper">
    <!-- 全スライドをまとめるラッパー -->
    <div class="swiper-wrapper">
        <!-- 各スライド -->
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
        ...
    </div>
    <!-- ページネーションを表示する場合 -->
    <div class="swiper-pagination"></div>
 
    <!-- 前後スライドへのナビゲーションボタン(矢印)を表示する場合 -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
 
    <!-- スクロールバーを表示する場合 -->
    <div class="swiper-scrollbar"></div>
</div>
スライドに画像やテキストなどを表示する場合は、.swiper-slide内にそれらの HTML を記述するのみです。
CSS (スライダーのサイズを指定)
必要なレイアウトは、ベースとなる swiper-bundle.min.css のみで配置してくれるので、ユーザー側で用意する最低限必要な CSS は、スライダー全体のサイズ(width/height)のみです。
.swiper{
    width: 600px;
    height: 300px;
}
フルスクリーン表示にするのであれば、以下のようにするだけです。
.swiper{
    width: 100%;
    height: 100vh;
}
JavaScript (スライダーを生成)
あとは、必要なパラメータをまとめて、Swiperオブジェクトを生成するのみでスライダーが表示されます。
var mySwiper = new Swiper ('.swiper', {
    // オプションパラメータ(一部のみ抜粋)
    loop: true, // 最後のスライドまで到達した場合、最初に戻らずに続けてスライド可能にするか。
    speed: 600, // スライドが切り替わるトランジション時間(ミリ秒)。
    slidesPerView: 4, // 何枚のスライドを表示するか
    spaceBetween: 10, // スライド間の余白サイズ(ピクセル)
    direction: 'horizontal', // スライド方向。 'horizontal'(水平) か 'vertical'(垂直)。effectオプションが 'slide' 以外は無効。
    effect: 'slide', // "slide", "fade"(フェード), "cube"(キューブ回転), "coverflow"(カバーフロー) または "flip"(平面回転)
    // スライダーの自動再生
    // autoplay: true  のみなら既定値での自動再生
    autoplay: {
      delay: 3000, // スライドが切り替わるまでの表示時間(ミリ秒)
      stopOnLast: false, // 最後のスライドまで表示されたら自動再生を中止するか
      disableOnInteraction: true // ユーザーのスワイプ操作を検出したら自動再生を中止するか
    },
    // レスポンシブ化条件
    breakpoints: {
      // 980ピクセル幅以下になったら
      980: {
        slidesPerView: 3,
        spaceBetween: 30
      },
      // 640ピクセル幅以下になったら
      640: {
        slidesPerView: 2,
        spaceBetween: 20
      }
    },
    // ページネーションを表示する場合
    pagination: {
      el: '.swiper-pagination',  // ページネーションを表示するセレクタ
    },
    // 前後スライドへのナビゲーションを表示する場合
    navigation: {
      nextEl: '.swiper-button-next', // 次のスライドボタンのセレクタ
      prevEl: '.swiper-button-prev', // 前のスライドボタンのセレクタ
    },
    // スクロールバーを表示する場合
    scrollbar: {
      el: '.swiper-scrollbar', // スクロールバーを表示するセレクタ
    }
  });
他にもたくさんのパラメータがあるので、詳しくは公式ドキュメントを参照してください。
Swiperパラメータ一覧
Swiper.js イベントリスナー
Swiper.js のイベントも豊富に用意されており、スライダーを生成後に、on メソッドでリスナーを登録できます。
なお、イベント関数内で実行中の対象スライダーインスタンスを取得するには、thisキーワードを指定します。
// スライダーを生成
var mySwiper = new Swiper('.swiper', {
  init: false, // 初期化はしない
  // その他のパラメータ
  ...
});
// スライダーの初期化(実行)
mySwiper.init();
// スライダーが初期化されたとき
mySwiper.on('init', function () {
  console.log('initialized');
});
// スライドが切り替わったとき
mySwiper.on('slideChange', function () {
  console.log('slide changed');
});
// 切り替わりのアニメーションが開始されたとき
mySwiper.on('slideChangeTransitionStart', function () {
  console.log('transition start');
});
// 切り替わりのアニメーションが終了したとき
mySwiper.on('slideChangeTransitionEnd', function () {
  // this キーワードで、対象のswiperインスタンスにアクセス可能
  console.log('transition end : active is ' + this.activeIndex);
});
// スライドの画像の読み込みが完了したとき(※スライド内にimgタグがある場合のみ)
mySwiper.on('imagesReady', function () {
  console.log('images ready');
});
イベントリスナーは、on メソッドではなく、スライダーの onパラメータ で定義すれば、スライダーの生成と同時にイベントを登録しておくことができ、より簡潔なコードになります。
var mySwiper = new Swiper ('.swiper', {
  ...
  // イベント
  on: {
    init: function(){
      // 任意の処理を実行
    },
    slideChange: function(){
      // 任意の処理を実行
    },
    slideChangeTransitionStart: function(){
      // 任意の処理を実行
    },
    slideChangeTransitionEnd: function(){
      // 任意の処理を実行
    },
    imagesReady: function(){
      // 任意の処理を実行
    }
  }
});
その他の Swiper.js のイベントについては公式ドキュメントをご覧ください。
Swiperイベント一覧
スライド内コンテンツにパララックス効果を与える
Swiper.js では、パラメータを追加するだけで、スライド(.swiper-slide)内に表示するテキストなどの任意のHTML要素にパララックス効果を施すこともできます。
パララックス効果を有効にする
parallax:true をオプションに含めるだけで、スライドが切り替わる際にスライド内の任意のコンテンツがパララックス効果を伴って表示されます。
var options = {
  ...
  parallax: true
};
var mySwiper = new Swiper('.swiper-container', options);
スライド内の要素にパララックス効果を定義する
パララックス効果を施すスライド内の要素には、data属性でスライドが切り替わる前の状態(移動距離、スケール、不透明度)と、元に状態に表示されるまでのアニメーション時間を指定しておきます。
パララックス効果用のdata属性
- data-swiper-parallax
 スライド方向に沿った表示前の移動距離を、数値(ピクセル)かパーセンテージ(%)で指定します。
 例 : data-swiper-parallax=”-80″, data-swiper-parallax=”-30%”
- data-swiper-parallax-x
 水平方向の表示前の移動距離を、数値(ピクセル)かパーセンテージ(%)で指定します。
- data-swiper-parallax-y
 垂直方向の表示前の移動距離を、数値(ピクセル)かパーセンテージ(%)で指定します。
- data-swiper-parallax-scale
 表示前の拡大率を指定します。
- data-swiper-parallax-opacity
 表示前の不透明度(0〜1)を指定します。
- data-swiper-parallax-duration
 パララックス効果のアニメーション時間をミリ秒で指定します。
<div class="swiper-wrapper">
    <div class="swiper-slide">
        <!-- 移動距離の指定 -->
        <div class="title" data-swiper-parallax="-100">Slide 1</div>
        <div class="subtitle" data-swiper-parallax="-200">Subtitle</div>
        <!-- 移動距離とアニメーション時間 -->
        <div class="text" data-swiper-parallax="-300" data-swiper-parallax-duration="600">
          <p>Lorem ipsum dolor sit amet, ...</p>
        </div>
        <!-- 不透明度の指定 -->
        <div data-swiper-parallax-opacity="0.5" >I will change opacity</div>
        <!-- 拡大率の指定 -->
        <div data-swiper-parallax-scale="0.15" >I will change scale</div>
    </div>
    ...
</div>
Swiper.js の基本的な仕組みと使い方が理解できたところで、Swiperだから簡単に実装できる少し凝ったスライダーを作ってみましょう。
Swiper.js で簡単に作れるスライダーのサンプル
カバーフロースライダー
中央にメインスライドを表示し、3次元効果でスライドが切り替わっていくカバーフローは、centeredSlides:trueとeffect:'coverflow' というパラメータを指定するだけで表現できます。
See the Pen Coverflow Slider with Swiper.js by digistate (@digistate) on CodePen.
このサンプルでは、画像がすべて読み込まれてからスライダーをフェードインで表示させるため、コンテナ要素(.swiper-container)は見えないようにしておき、SwiperのimagesReady イベントで画像の読み込みが完了したら、コンテナ要素から非表示用の.loadingセレクタを削除してスライダーが表示されるようにしています。
SwiperコンテナのHTML
<section class="swiper loading"> ... </section>
imagesReadyイベント
var options = {
  effect: 'coverflow',
  ...
  on: {
    imagesReady: function(){
      this.el.classList.remove('loading');
    }
  }
var mySwiper = new Swiper('.swiper', options);
ちなみに、このサンプルでは実際に表示される画像はスライド要素(.swiper-slide)の背景画像(background-image)であり、img 要素は imagesReady イベントで画像ファイルの読み込み完了を検知するためだけに背景画像と同じURLを指定して、これ自体はCSS で非表示(display:none)にしています。
3D キューブ回転スライダー
スライドを立体に見えるように配置し、回転するキューブ状のスライダーを表示するには、effect:'cube' というパラメータを付けます。
See the Pen 3D Cube Slider with Swiper.js by digistate (@digistate) on CodePen.
このサンプルでは、キューブが自動または手動で回転する際に、スライドが見切れないよう、Swipeのイベントを利用してトランジションの開始時に縮小し、トランジション終了後に元のスケールに戻すようにしています。
イベント処理
var isMove = false,
    options = {
      ...
      // イベント
      on: {
        ...
        // ユーザー操作によりスライドが移動されたとき
        touchMove: function(event){
          if (!isMove) {
            this.el.classList.remove('scale-in');
            this.el.classList.add('scale-out');
            isMove = true;
          }
        },
        // ユーザー操作が解除されたとき
        touchEnd: function(event){
          this.el.classList.remove('scale-out');
          this.el.classList.add('scale-in');
          setTimeout(function(){
            isMove = false;
          }, 300);
        },
        // トランジション開始時
        slideChangeTransitionStart: function(){
          if (!isMove) {
            this.el.classList.remove('scale-in');
            this.el.classList.add('scale-out');
          }
        },
        // トランジション終了時
        slideChangeTransitionEnd: function(){
          if (!isMove) {
            this.el.classList.remove('scale-out');
            this.el.classList.add('scale-in');
          }
        }
      }
    };
水平パララックス効果を伴うスライダー
最後は、スライドが切り替わる際、スライド内に表示させている背景画像要素を微妙に移動(translate)させることで、スライド自体の移動の動きと背景画像の動きにずれを生じさせて視差(パララックス)効果を施したサンプルです。
各スライドのトランジション時の進捗状況は、watchSlidesProgress:true というパラメータを指定し、progressイベントで受け取ることができます。
さらに、touchStart イベントでスライドがクリック(タップ)された際にはすべてのスライド要素の transition を一旦クリアし、setTransition イベントでトランジションアニメーションが開始された際に、トランジション時間(transition-duration)を受け取り、スライド要素(.swiper-slide)と背景画像要素(.slide-bgimg)に transition を再びセットします。
See the Pen Horizontal parallax sliding slider with Swiper.js by digistate (@digistate) on CodePen.
このサンプルでは、切り替わる際の動きはスライド自体とは別で処理させるため、スライド要素(.swiper-slide)に background-image は指定せず、その配下に別途背景画像用の要素(figure)を設けています。
<div class="swiper-slide">
  <figure class="slide-bgimg" style="background-image:url(画像URL)">
    <img src="画像URL" class="entity-img" />
  </figure>
</div>
参考
https://github.com/nolimits4web/Swiper/issues/1497
さらに、メインスライダーとは別にページネーション用に同じスライド数のスライダーを用意し、slideToClickedSlide:true パラメータによって選択されたスライドへの移動を有効にし、双方が制御関係にあるように紐付けることで、サムネイルナビゲーション付きのスライダーができあがります。
mainSlider.controller.control = navSlider; navSlider.controller.control = mainSlider;
data-swiper-parallax 属性による水平パララックス効果を表現した例
2019/4/9:追記
Swiper.js がサポートするパララックスコンポーネントを利用すれば、対象要素に data-swiper-parallax 属性を与えるだけで、上記サンプルの progress イベントなどを利用して JavaScript を組まなくても、より簡素なコードで上記同様のパララックススクロールで切り替わるスライドを表示できます。
パララックスコンポーネントについてはこちら
  See the Pen 
  Horizontal parallax sliding slider #2 with Swiper.js (More easier) by digistate (@digistate)
  on CodePen.
Swiper.js を利用したスライダーのサンプルをご紹介しましたが、Swiper.js はjQueryが不要であるだけでなく、特に3次元のトランジション動作を施したスライダーでも非常に簡単に実装できることが、定番のSlickやbxSliderなどと比べても優れていると感じました。
以前公開した「slick.js に動画スライドを含めて自動再生するスライダーの実装方法」の内容を、Swiper.js に移行することも容易だと思いますので、今後リリースするWordPressテーマには、Swiper.js をベースにした画像と動画(YouTube, Vimeo, HTML5 Video)の混在スライダーを組み込んでみたいと思います。
あくまでサンプルで公開したもので汎用性や完全性は何も考慮していないのですが、そのテーマでは関数やセレクタ名もサンプルそのままで、インラインで未圧縮のまま日本語のコメントだらけのコードだったので、何かバッティングやAPIの仕様変更が起きた際にはちゃんと処理を理解して対応する意志があるといいのですが。。
