DigiPress

Highly Flexible WordPress Theme

メニュー

便利すぎ!jQuery不要のスライダー「Swiper.js」で色々と遊んでみよう

便利すぎ!jQuery不要のスライダー「Swiper.js」で色々と遊んでみよう

汎用性に優れている、超定番のjQueryベースのスライダーライブラリといえば、「slick」、「bxSlider」、「FlexSlider」 あたりでしょうか。

しかし、これらの名だたるライブラリよりも、総合的に機能が豊富カスタマイズ性にも富み、しかもjQueryに依存しないJavascriptスライダーライブラリとして人気を集めているのが、「Swiper.js」です。

試してみたところ、モバイルデバイスとレスポンシブ表示にも対応しているだけでなく、パラメータが豊富で非常に凝ったスライドショーでもあまりに簡単に実装できる優れものだったので、いくつかのサンプルと共にご紹介します。

Swiper.js の基本的な使い方

Swiper.js を使用するには、headセクション内にCSSと、</body>の前にメインのJavascriptファイルを読み込んでおきます。
ライブラリ自体をダウンロードするか、CDN経由でも利用できます。

Swiper CDN

ライブラリの読み込み

CSS

<head>
  ...
  <link rel="stylesheet" href="path/to/swiper.min.css" />

  <!-- CDNの場合 -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/css/swiper.min.css" />
</head>

Javascript

<body>
  ...
  <script src="path/to/swiper.min.js"></script>

  <!-- CDNの場合 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.0.7/js/swiper.min.js"></script>
</body>

スライダーのHTML

基本となるHTML構成は、以下のようにします。

<!-- スライダー全体を括るメインコンテナ -->
<div class="swiper-container">
    <!-- 全スライドをまとめるラッパー -->
    <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.min.css のみで配置してくれるので、ユーザー側で用意する最低限必要なCSSは、スライダー全体のサイズ(width/height)のみです。

.swiper-container {
    width: 600px;
    height: 300px;
}

フルスクリーン表示にするのであれば、以下のようにするだけです。

.swiper-container {
    width: 100%;
    height: 100vh;
}

Javascript(スライダーを生成)

あとは、必要なパラメータをまとめて、Swiperオブジェクトを生成するのみでスライダーが表示されます。

var mySwiper = new Swiper ('.swiper-container', {
    // オプションパラメータ(一部のみ抜粋)
    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イベントリスナー

Swiperのイベントも豊富に用意されており、スライダーを生成後に、onメソッドでリスナーを登録できます。
なお、イベント関数内で実行中の対象スライダーインスタンスを取得するには、thisキーワードを指定します。

// スライダーを生成
var mySwiper = new Swiper('.swiper-container', {
  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-container', {
  ...
  // イベント
  on: {
    init: function(){
      // 任意の処理を実行
    },
    slideChange: function(){
      // 任意の処理を実行
    },
    slideChangeTransitionStart: function(){
      // 任意の処理を実行
    },
    slideChangeTransitionEnd: function(){
      // 任意の処理を実行
    },
    imagesReady: function(){
      // 任意の処理を実行
    }
  }
});

その他のSwiperのイベントについては公式ドキュメントをご覧ください。
Swiperイベント一覧

スライド内コンテンツにパララックス効果を与える

Swiperでは、パラメータを追加するだけで、スライド(.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の基本的な仕組みと使い方が理解できたところで、Swiperだから簡単に実装できる少し凝ったスライダーを作ってみましょう。

Swiperで簡単に作れるスライダーのサンプル

カバーフロースライダー

中央にメインスライドを表示し、3次元効果でスライドが切り替わっていくカバーフローは、centeredSlides:trueeffect:'coverflow' というパラメータを指定するだけで表現できます。

See the Pen Coverflow Slider with Swiper.js by digistate (@digistate) on CodePen.


このサンプルでは、画像がすべて読み込まれてからスライダーをフェードインで表示させるため、コンテナ要素(.swiper-container)は見えないようにしておき、SwiperのimagesReadyイベントで画像の読み込みが完了したら、コンテナ要素から非表示用の.loadingセレクタを削除してスライダーが表示されるようにしています。

SwiperコンテナのHTML

<section class="swiper-container loading">
...
</section>

imagesReadyイベント

var options = {
  effect: 'coverflow',
  ...
  on: {
    imagesReady: function(){
      this.el.classList.remove('loading');
    }
  }
var mySwiper = new Swiper('.swiper-container', 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;

Swiperを利用したスライダーのサンプルをご紹介しましたが、SwiperはjQueryが不要であるだけでなく、特に3次元のトランジション動作を施したスライダーでも非常に簡単に実装できることが、定番のSlickbxSliderなどと比べても優れていると感じました。

以前公開した「slick.jsに動画スライドを含めて自動再生するスライダーの実装方法」の内容を、Swipeに移行することも容易だと思いますので、今後リリースするWordPressテーマには、Swiperをベースにした画像と動画(YouTube, Vimeo, HTML5 Video)の混在スライダーを組み込んでみたいと思います。

ちなみに、slick.jsに動画スライドを含めて自動再生するスライダーの実装方法のサンプルコードは、記事公開後に、ある業者が販売しているWordPressテーマのトップページ用のスライダーに必要な修正もなくほぼそのまま転用された状態で組み込まれ、販売されていました。。
あくまでサンプルで公開したもので汎用性や完全性は何も考慮していないのですが、そのテーマでは関数やセレクタ名もサンプルそのままで、インラインで未圧縮のまま日本語のコメントだらけのコードだったので、何かバッティングやAPIの仕様変更が起きた際にはちゃんと処理を理解して対応する意志があるといいのですが。。
Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks
Pinterest
Pocket
Feedly