スライダープラグイン Swiper(v5/v6)の使い方
jQuery 不要でレスポンシブ及びタッチデバイス(スマホやタブレット)対応のスライダープラグイン Swiper の基本的な設定方法や使い方についての覚書(解説)です。
以下で扱っている Swiper のバージョンは 5 以降です。各バージョンでは読み込むファイル名やダウンロード方法などが異なっています。また、バージョン 7 では、スライダーのメインコンテナに指定するクラスが swiper-container から swiper に変更になっています。
サポートされているのはモダンブラウザのみで、バージョン 5.0 から IE は完全に対象外になっています。
- Swiper 公式サイト:https://swiperjs.com/
- Swiper GitHub ページ:https://github.com/nolimits4web/swiper
- Swiper ダウンロードページ:https://github.com/nolimits4web/swiper/releases
- Swiper 変更履歴:Change Log
関連ページ
作成日:2020年2月23日
Swiper の実装方法
Swiper を利用するには必要なファイルをダウンロードするか CDN で読み込みます。CDN で読み込むのが簡単ですが、本番環境でどちらを使うかは検討する必要があるかも知れません(バージョンの変更により CDN のアドレスが変更になる可能性があります)。
または npm でインストールすることもできます。
関連ページ:
CDN
CDN を利用すれば Swiper に必要なファイル(CSS と JavaScript)を簡単に読み込むことができます。
CSS は <head>〜</head> 内で読み込み、JavaScript は </body> の直前などで読み込みます。
<!DOCTYPE html> <html lang="ja"> <head> ... <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" /> </head> <body> ... <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script> </body> </html>
バージョン5 から CDN の読み込み先が以下に変更になっています。
<link rel="stylesheet" href="https://unpkg.com/swiper/css/swiper.css"><link rel="stylesheet" href="https://unpkg.com/swiper/css/swiper.min.css">
<script src="https://unpkg.com/swiper/js/swiper.js"></script><script src="https://unpkg.com/swiper/js/swiper.min.js"></script>
バージョン6
バージョン6 ではファイル名や読み込み先のフォルダが変更になっています。
swiper.css は swiper-bundle.css に、swiper.js は swiper-bundle.js に変更になっていて、パスからは /css や /js がなくなっています。
以下はバージョン6 の CDN 経由での読み込むファイルです。特に理由がなければミニファイ化された swiper-bundle.min.css や swiper-bundle.min.js の方を読み込みます。
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.css" /> <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" />
<script src="https://unpkg.com/swiper/swiper-bundle.js"></script> <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
Getting Started With Swiper:Use Swiper from CDN
バージョン 6 での変更点:6.0.0 - Released on July 3rd, 2020 (Changelog)
バージョン 7
以下はバージョン 7 の CDN です。
<!-- CSS --> <link rel="stylesheet" href="https://unpkg.com/swiper@7/swiper-bundle.min.css"/> <!-- JavaScript --> <script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
バージョン 7 での変更点:7.0.0 (2021-08-25)
ダウンロード
ダウンロードして使用することもできます。ダウンロードページ から最新版をダウンロードします。
以下はバージョン 5 での例です(バージョン 6)。
ダウンロードしたファイルを展開すると以下のようなディレクトリ構成になっています。いろいろなファイルが入っていますが、必要なファイルは以下の2つ(CSS と JavaScript)です。
- swiper.min.css
- swiper.min.js
以下はバージョン 5.3.1 の例です。
Swiper の読み込み
「swiper.min.css」と「swiper.min.js」を環境に合わせて配置し、それらのファイルを読み込みます。
CSS(swiper.min.css)は <head>〜</head> 内で読み込み、JavaScript(swiper.min.js)は </body> の直前などで読み込みます。ファイルへのパスは環境に合わせて適宜変更します。
<!DOCTYPE html> <html lang="ja"> <head> ... <link rel="stylesheet" href="path/to/swiper.min.css"> </head> <body> ... <script src="path/to/swiper.min.js"></script> </body> </html>
バージョン 6 以降の場合
バージョン 6 からは以下のページから個別にファイルをダウンロードできます(バージョン 5 以前のファイルもダウンロード可能)。
必要なファイルは以下の2つ(CSS と JavaScript)です。
- swiper-bundle.min.css
- swiper-bundle.min.js
ファイルを選択して開いたページで「View Raw」をクリックするとそのファイルが開くので、コピーするか保存します。
「swiper-bundle.min.css」と「swiper-bundle.min.js」を環境に合わせて配置し、それらのファイルを読み込みます。
<!DOCTYPE html> <html lang="ja"> <head> ... <link rel="stylesheet" href="path/to/swiper-bundle.min.css"> </head> <body> ... <script src="path/to/swiper-bundle.min.js"></script> </body> </html>
スライダーの HTML
以下はスライダーの基本的なレイアウトの HTML の例です。3つのスライド(画像)をそれぞれ .swiper-slide 内に配置してスライダーで表示します。
以下のクラスの div 要素はスライダーの構造に必須の要素です。
- swiper-container(スライダーのコンテナ)
- swiper-wrapper(追加のラッパー)
- swiper-slide(各スライドを入れる要素)
<!-- スライダーのメインコンテナの div 要素 --> <div class="swiper-container"> <!-- ラッパーの(スライドを囲む) div 要素 --> <div class="swiper-wrapper"> <!-- それぞれのスライドの div 要素 --> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <!-- ページネーションの div 要素 --> <div class="swiper-pagination"></div> <!-- ナビゲーションボタンの div 要素--> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> <!-- スクロールバーの div 要素 --> <div class="swiper-scrollbar"></div> </div>
ページネーションやナビゲーションボタン、スクロールバーを表示するには以下のクラスの div 要素を記述します。また、同時にスライダーの初期化の際にそれらを表示するためのオプションを設定します。
- swiper-pagination(ページネーション)
- swiper-button-prev(「前へ」の矢印ボタン)
- swiper-button-next(「次へ」の矢印ボタン)
- swiper-scrollbar(スクロールバー)
スライド画像の遅延読み込み(Lazy Loading)を有効にする場合は、マークアップが異なります。
Swiper 7
バージョン 7 では、スライダーのメインコンテナに指定するクラスが swiper-container から swiper に変更になっています。
<div class="swiper"> <!-- 変更 --> <div class="swiper-wrapper"> <div class="swiper-slide">Slide 1</div> ... </div> </div>
その他の変更などの詳細: Migration Guide to Swiper 7
【注意】
以降のサンプルでは、スライダーのメインコンテナの要素に .swiper-container を指定しています(バージョン 6 までのメインコンテナのクラス)。
バージョン 7 の場合は、CSS も含め .swiper-container を .swiper に変更する必要があります。
スライダーの CSS
必要に応じて CSS でスタイルを指定します。
スライダーのサイズやナビゲーションなどのスタイルは CSS で設定することができます。
以下の例では、コンテナに最大幅(max-width)とマージン(margin)を指定して、スライダーのサイズと配置を指定しています。
環境に合わせて指定します。
.swiper-container { max-width: 500px; margin: 30px 0; }
Swiper の CSS
スライダーやナビゲーションボタンなどにデフォルトで設定されているスタイルは CDN やダウンロードした swiper.css(バージョン6以降は swiper-bundle.css)で確認できます。
以下はバージョン5 の swiper.css で設定されているデフォルトのスタイルの一部抜粋です。
.swiper-container { margin-left: auto; margin-right: auto; position: relative; overflow: hidden; list-style: none; padding: 0; /* Fix of Webkit flickering */ z-index: 1; } .swiper-wrapper { position: relative; width: 100%; height: 100%; z-index: 1; display: flex; transition-property: transform; box-sizing: content-box; } .swiper-slide { flex-shrink: 0; width: 100%; height: 100%; position: relative; transition-property: transform; } .swiper-button-prev, .swiper-button-next { position: absolute; top: 50%; width: calc(var(--swiper-navigation-size) / 44 * 27); height: var(--swiper-navigation-size); margin-top: calc(-1 * var(--swiper-navigation-size) / 2); z-index: 10; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--swiper-navigation-color, var(--swiper-theme-color)); } .swiper-pagination { position: absolute; text-align: center; transition: 300ms opacity; transform: translate3d(0, 0, 0); z-index: 10; } .swiper-pagination-bullet { width: 8px; height: 8px; display: inline-block; border-radius: 100%; background: #000; opacity: 0.2; }
バージョン 7 では swiper-container が .swiper に変更になっています。
/* swiper-container が .swiper に変更 */ .swiper { margin-left: auto; margin-right: auto; position: relative; overflow: hidden; list-style: none; padding: 0; /* Fix of Webkit flickering */ z-index: 1; } .swiper-wrapper { position: relative; width: 100%; height: 100%; z-index: 1; display: flex; transition-property: transform; box-sizing: content-box; }
テーマカラー
Swiper の CSS には CSS 変数を使ってテーマカラーやナビゲーションのサイズなどが設定されています。
:root { --swiper-theme-color: #007aff; } :root { --swiper-navigation-size: 44px; /* --swiper-navigation-color: var(--swiper-theme-color); */ } :root { /* --swiper-pagination-color: var(--swiper-theme-color); */ }
例えば、以下のような独自の CSS でスタイルを設定(上書き)すると、ナビゲーションの色を黒(#000000)に、ページネーションの色を白(#ffffff)に変更することができます。
:root { --swiper-navigation-color: #000000; --swiper-pagination-color: #ffffff; }
スライダーの初期化
スライダー(Swiper)の HTML が用意できたら、new 演算子と Swiper() メソッドを使って初期化する必要があります。
Swiper() メソッドにはスライダーのコンテナ要素(セレクタ)を指定し、必要なオプションを指定して実行します。Swiper() メソッドはスライダーのインスタンス(Swiper オブジェクト)を生成し返します。
let スライダーインスタンス(変数) = new Swiper('セレクタ', { オプション(オブジェクト) });
以下はスライダーのコンテナ要素のセレクタ .swiper-container を指定し、ナビゲーションのオプション(navigation)を指定してスライダーのインスタンスを生成して変数 mySwiper に格納する例です。
セレクタはスライダーのコンテナ要素に .swiper-container に加えて別のクラス名や id 属性を指定してあれば、それらを指定することもできます。
let mySwiper = new Swiper('.swiper-container', { navigation: { //ナビゲーションのオプション(矢印ボタンの要素を指定) nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', } });
初期化後は生成したインスタンスのメソッドやプロパティを使うことができます。
以下は生成したインスタンス mySwiper の on メソッド使ってスライドが変更された際のイベント slideChange にコンソールに何番目のスライドかを表示する処理を登録する例です。
mySwiper.on('slideChange', function () { console.log('現在のスライド番号: ' + (mySwiper.realIndex + 1)); });
初期化の JavaScript の記述は </body> タグの直前に記述するか、別ファイルに記述して </body> タグの直前などで読み込みます(Swiper 本体の読み込みの後)。
<body> ... <script> let mySwiper = new Swiper ('.swiper-container', { // オプションの設定 navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, ・・・必要なだけオプションを指定・・・ }); </script> </body>
以下はオプションに loop(最後に達したら先頭に戻る)の設定や pagination(ページネーション)、navigation(ナビゲーションボタン)、scrollbar(スクロールバー)の設定を指定して初期化する例です。
<script> let mySwiper = new Swiper ('.swiper-container', { // 以下にオプションを設定 loop: true, //最後に達したら先頭に戻る //ページネーション表示の設定 pagination: { el: '.swiper-pagination', //ページネーションの要素 type: 'bullets', //ページネーションの種類 clickable: true, //クリックに反応させる }, //ナビゲーションボタン(矢印)表示の設定 navigation: { nextEl: '.swiper-button-next', //「次へボタン」要素の指定 prevEl: '.swiper-button-prev', //「前へボタン」要素の指定 }, //スクロールバー表示の設定 scrollbar: { el: '.swiper-scrollbar', //要素の指定 }, }); </script>
上記の初期化と HTML 及び CSS で以下のようなスライダーが表示されます。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></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-container { max-width: 500px; margin: 30px 0; }
オプションを別途定義
オプションのオブジェクトを別途定義しておき、初期化することもできます。オプションの定義を先に記述します。以下は前述の初期化を書き換えた例です。
//オプションの定義(初期化の式より先に記述) let options = { loop: true, pagination: { el: '.swiper-pagination', type: 'bullets', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', hideOnClick: true, }, scrollbar: { el: '.swiper-scrollbar', }, }; //上記オプションを使って初期化 let mySwiper = new Swiper ('.swiper-container', options);
背景画像を指定
前述の例では各スライドを入れる要素(.swiper-slide)の中に img 要素を配置しましたが、.swiper-slide を指定した要素(またはその子要素)に背景画像を指定することもできます。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide bg-slide-image" style="background-image: url(images/sample_01.png)"></div> <div class="swiper-slide bg-slide-image" style="background-image: url(images/sample_02.png)"></div> <div class="swiper-slide bg-slide-image" style="background-image: url(images/sample_03.png)"></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>
以下では .bg-slide-image というクラスを追加して背景画像のスタイルを設定しています。他に img 要素を使ったスライダーがなければ、.swiper-slide に設定することもできるかと思います。また、個々の画像はインラインスタイルで指定していますが、id を付与してスタイルシートで指定することもできます。
.swiper-container { max-width: 500px; margin: 30px 0; } /* 背景画像のスタイルの設定 */ .bg-slide-image { width: 600px; height: 370px; background-size: cover; background-position: center center; background-repeat: no-repeat; }
以下はスライダーの初期化です(前述の例と同じ)。
<script> let mySwiper = new Swiper ('.swiper-container', { // 以下にオプションを設定 loop: true, //最後に達したら先頭に戻る //ページネーション表示の設定 pagination: { el: '.swiper-pagination', //ページネーションの要素 type: 'bullets', //ページネーションの種類 clickable: true, //クリックに反応させる }, //ナビゲーションボタン(矢印)表示の設定 navigation: { nextEl: '.swiper-button-next', //「次へボタン」要素の指定 prevEl: '.swiper-button-prev', //「前へボタン」要素の指定 }, //スクロールバー表示の設定 scrollbar: { el: '.swiper-scrollbar', //要素の指定 }, }); </script>
以下は各スライドを入れる要素(.swiper-slide)の中に div 要素を配置してその要素に背景画像を指定しています。また、.swiper-slide の中に背景画像と一緒にスライドさせるコンテンツ(.slide-content の div 要素)を追加しています。スライダーの初期化は前述の例と同じです。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="bg-slide-image" style="background-image: url(images/sample_01.png)"> </div> <div class="slide-content"> <p>Content 01</p> </div> </div> <div class="swiper-slide"> <div class="bg-slide-image" style="background-image: url(images/sample_02.png)"> </div> <div class="slide-content"> <p>Content 02</p> </div> </div> <div class="swiper-slide"> <div class="bg-slide-image" style="background-image: url(images/sample_03.png)"> </div> <div class="slide-content"> <p>Content 03</p> </div> </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 .slide-content p { position: absolute; top: 20%; left: 50%; transform: translate(-50%, -50%); color: #FFF; text-shadow: .5px .5px rgba(0,0,0,0.6); margin: 0; padding: 0; font-size: 18px; }
background-attachment : fixed
スライダーの要素(.swiper-slide)の背景画像のスタイルに background-attachment に fixed を指定するとスライダーは機能しません。
スライドはスクロールではなく CSS transforms を使用しているため、機能しないようです。以下に「background-attachment に fixed を指定した場合の問題」に対する作者の回答があります(Version 4 に関してですが、Version 5 や 6 でも同じです)。
パラメータ
Swiper には数多くのパラメータが用意されていて、それらを使ってスライダーをカスタマイズすることができます。以下はその中のほんの一部です。
すべてのパラメータは「Swiper Parameters」で確認することができます。
パラメータ | データ型 | デフォルト | 説明 |
---|---|---|---|
initialSlide | number | 0 | 開始するスライドのインデックスを指定(0 が1番目のスライド) |
direction | string | 'horizontal' | スライド方向を指定。'horizontal':水平(横)方向、'vertical':垂直(縦)方向。'vertical'を指定した場合はコンテナに height や max-height を指定。 |
speed | number | 300 | スライドのスピードをミリ秒で指定 |
autoHeight | boolean | false | true を指定すると現在のスライドに合わせて高さを自動的に調整 |
effect | string | 'slide' | スライドのエフェクトを指定。指定できるエフェクトは "slide", "fade", "cube", "coverflow" "flip"。"fade" を指定した場合は、下の要素が表示されないように crossFade: true を指定します。 |
spaceBetween | number | 0 | スライド間の余白を px で指定。要素にマージンを指定している場合、ナビゲーションが正常に機能しない可能性あり |
slidesPerView | number or 'auto' | 1 | 一度に表示するスライドの数。数値または 'auto' を指定。小数点以下(例 1.5 など)も指定可能。auto を指定して同時に loop: true を設定する場合は、loopedSlides パラメータを指定する必要あり |
slidesPerGroup | number | 1 | 同時にスライドさせるスライドの数 |
slideToClickedSlide | boolean | false | true に設定すると、任意のスライドをクリックするとそのスライドへ移行(スライド)します |
centeredSlides | boolean | false | true を指定するとアクティブなスライドを中央に配置(通常アクティブなスライドは左端に配置)。例えば slidesPerView で 1.4 と指定して centeredSlides: true とするとアクティブなスライドの左右に20%ずつの前後の画像が表示されます。 |
loop | boolean | false | true を指定するとスライドをループモードにします(最後に達したら先頭に戻る)。その場合、ループの構造上、前後に複製されたスライドが生成され、それらには swiper-slide-duplicate などのクラスが付与されます。 |
loopedSlides | number | null | slidesPerView に auto を設定した場合、このパラメータで(前後に)複製するスライドの数を指定します。 |
breakpoints | object | ブレークポイント(画面サイズ)ごとにそれぞれ異なるパラメータを設定できます。 | |
on | object | イベントの登録 |
以下はスライドのエフェクトを coverflow にし、ループを有効にしてスライドの最後に達したら先頭に戻るようにする例です。
slidesPerView:2 で表示するスライド数を指定しています。この例の場合は、centeredSlides も指定しているので、左右に半分ずつのスライドが表示されています。
また、デフォルトの bullets タイプのページネーションを表示しアイコンをクリックすると対応するスライドに移動し、デフォルトのナビゲーションボタンを表示させています。
let mySwiper = new Swiper ('.swiper-container', { loop: true, //ループ可能(ループモードを有効に) slidesPerView:2, //スライドを2つ(分)表示 centeredSlides : true, //アクティブなスライドを中央に表示 effect: 'coverflow', //スライドのエフェクトを coverflow に pagination: { //ページネーションを表示 el: '.swiper-pagination', clickable: true, //アイコンをクリックすると対応するスライドに移動 }, navigation: { //ナビゲーションボタンを表示 nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });
※ パラメータは上記の例のように初期化する際に指定することができますが、HTML の data 属性を使って指定することもできます。詳細は data 属性を使ってパラメータを設定 を御覧ください。
Breakpoints
breakpoints パラメータを使うと、画面サイズごとに異なるパラメータを設定することができます。
但し、ブレークポイントごとに変更できるパラメータは slidesPerView, slidesPerGroup, spaceBetween, slidesPerColumn などに限定されていて、例えば loop や effect は設定できません。
以下は画面幅により一度に表示するスライドの数(slidesPerView)を変える例です。
let mySwiper = new Swiper ('.swiper-container', { // デフォルトの設定 slidesPerView: 1, spaceBetween: 0, // レスポンシブブレーポイント(画面幅による設定) breakpoints: { // 画面幅が 640px 以上の場合(window width >= 640px) 640: { slidesPerView: 2, spaceBetween: 5 }, // 画面幅が 980px 以上の場合(window width >= 980px) 980: { slidesPerView: 3, spaceBetween: 10 } }, pagination: { el: '.swiper-pagination', clickable: true, }, });
easing(イージング)
Swiper には easing を指定するパラメータはありませんが、.swiper-wrapper を指定した要素に CSS の transition-timing-function を指定することでスライドの動きのイージングを設定することができます。
.swiper-wrapper { transition-timing-function: ease-in; /* ease-in を指定する例 */ }
以下の例では .swiper-wrapper を指定した要素に別途 easeInOutBack というクラスを指定して、そのクラスを使ったセレクタに対して transition-timing-function を設定しています。
<div class="swiper-container"> <div class="swiper-wrapperr easeInOutBack"><!--.swiper-wrapper を指定した要素--> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <div class="swiper-pagination"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div>
easeInOutBack というイージングは CSS にはないので、cubic-bezierr 関数を使って設定しています。
.swiper-wrapper.easeInOutBack { transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55) ; }
この例では初期化の際に speed を 800 に設定しています。
let mySwiper = new Swiper ('.swiper-container', { speed: 800, loop: true, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, pagination: { el: '.swiper-pagination', clickable: true, }, });
swiper-bundle.css には以下のような記述があります。
.swiper-free-mode > .swiper-wrapper { transition-timing-function: ease-out; margin: 0 auto; }
イベント(Events)
Swiper には数多くのイベントも用意されていて、カスタマイズする際に利用することができます。
利用可能なイベントは「API/Events」に掲載されています。
また、個々のコンポーネントごとにもイベントが用意されているものもあり、API ページの各コンポーネントの項目で確認することができます。
イベント(リスナー)を登録するには以下の2つの方法があります。
on パラメータ
初期化の際に on パラメータを使ってイベントを登録できます。
let mySwiper = new Swiper('.swiper-container', { // 初期化の際に登録 // ...初期化の処理 on: { init: function () { console.log('swiper initialized'); }, }, };
on メソッド
初期化の後に on メソッドを使ってイベントを登録することもできます。
let mySwiper = new Swiper('.swiper-container', { // ...初期化の処理 }; // 初期化の後で Swiper のインスタンスの on メソッドで登録 mySwiper.on('slideChange', function () { console.log('slide changed'); });
以下の例は初期化の際に init イベントでナビゲーションボタンに swiper-button-white というクラスを指定して色を白に変更しています。また初期化の後では on メソッドで slideChange イベントに現在のスライド番号をコンソールに出力する処理を登録しています。
以下の例では、スライダーのコンテナ要素に .swiper-container に加えて id 属性(swiper01)を指定して、そのセレクタを使って初期化しています。
let mySwiper01 = new Swiper ('#swiper01', { navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, on: { // 初期化の際に init イベントを登録 init: function () { const prev_btn = document.querySelector('#swiper01 .swiper-button-prev'); const next_btn = document.querySelector('#swiper01 .swiper-button-next'); prev_btn.classList.add('swiper-button-white'); next_btn.classList.add('swiper-button-white'); }, }, }); // 初期化の後で slideChange イベントを登録(初期化の際に登録することも可能) mySwiper01.on('slideChange', function () { console.log('現在のスライド番号: ' + (this.activeIndex + 1)); });
イベントハンドラ(処理登録)の中で this は常に Swiper のインスタンスを意味します。上記の場合、this.activeIndex は mySwiper01.activeIndex と同じです。
上記のコンソールに出力する処理では Swiper インスタンスのプロパティ activeIndex を参照しています。
イベント名 | 意味 |
---|---|
slideChange | スライドが遷移する(変わる)ときに発火 |
realIndexChange | realIndex が変わるときに発火 |
reachBeginning | 最初のスライド(初期位置)に達したときに発火 |
reachEnd | 最後のスライドに達したときに発火 |
resize | window のサイズ変更時に発火 |
beforeResize | resize ハンドラの前に発火 |
プロパティやメソッド
初期化でインスタンスを生成した後では、Swiper インスタンスのプロパティやメソッドを使用することができます。Swiper インスタンスのプロパティやメソッドは「Slider Methods & Properties」に掲載されています。
また、イベント同様、コンポーネントごとに用意されているプロパティやメソッドもあります。
プロパティ名 | 意味 |
---|---|
.width | コンテナの幅 |
.height | コンテナの高さ |
.activeIndex | アクティブなスライドのインデックス |
.realIndex | ループモードでの複製されたスライドを考慮したアクティブなスライドのインデックス |
.params | 初期化の際に設定されたパラメータのオブジェクト。例えば loop の設定は mySwiper.params.loop で取得(mySwiper はスライダーインスタンス) |
コントロール
ナビゲーションボタンやページネーション、スクロールバーを表示するにはそれらの要素を HTML に記述して初期化の際にオプションで指定します。
また、デフォルトのスタイルを変更するには追加の CSS で上書き(設定)します。
ページネーション(Pagination)
ページネーション(何枚目のスライドかを示すアイコン)を表示するには、 HTML に swiper-pagination クラスの div 要素を記述します。
<div class="swiper-pagination"></div> <!-- 以下のクラスを追加指定するとデフォルトの青から白や黒に変更可能(※ Version 5 の場合のみ) --> <!-- 白色のページネーション .swiper-pagination-white(※ Version 5 の場合のみ) --> <div class="swiper-pagination swiper-pagination-white"></div> <!-- 黒色のページネーション .swiper-pagination-black (※ Version 5 の場合のみ)--> <div class="swiper-pagination swiper-pagination-black"></div>
(追記)Version 5 では .swiper-pagination-white などが用意されていましたが、Version 6 以降では用意されていません。テーマカラーを編集することで色を変更することができます。
そして初期化の際にオプションの pagination を指定して必要なパラメータを設定します。
let mySwiper = new Swiper('.swiper-container', { pagination: { el: '.swiper-pagination', //ページネーションの要素のセレクタ type: 'bullets', //ページネーションのタイプ }, });
初期化の際には以下のパラメータを指定することができます。
パラメータ | データ型 | デフォルト | 説明 |
---|---|---|---|
el | string | null | ページネーションの要素の CSS セレクタまたは HTML 要素 |
type | string | 'bullets' | タイプ(表示形態)を指定。"bullets", "fraction", "progressbar" または "custom" を指定可能 |
bulletElement | string | 'span' | type で bullets を指定した場合に、それぞれのアイコンを表示する HTML 要素を指定。 |
dynamicBullets | boolean | false | スライドが多数ある場合に、ページネーションのすべてのアイコンを表示せずに dynamicMainBullets で指定した数のアイコンを表示。 |
dynamicMainBullets | number | 1 | dynamicBullets が有効(true)の場合に表示するメインアイコンの数 |
clickable | boolean | false | true を指定すると、ページネーションのアイコンをクリックすると対応するスライドを表示 |
renderBullet | function | null | bullets タイプのページネーションのアイコンをカスタマイズする際に使用。引数にインデックスとアイコンの要素のクラス名(className)を取る関数を指定。function(index, className){ アイコンの HTML を返す }。CSS でスタイルを指定(サンプル参照) |
bulletClass | string | 'swiper-pagination-bullet' | bullets タイプのページネーションのアイコンに付与されるクラス |
bulletActiveClass | string | 'swiper-pagination-bullet-active' | bullets タイプのアクティブなページネーションのアイコンに付与されるクラス |
以下は初期化の際に、type を bullets(デフォルト)、clickable を true に設定した場合に、出力されるページネーションの HTML の例です。
type が bullets なので swiper-pagination-bullets というクラスが付き、clickable を true に設定したので、swiper-pagination-clickable というクラスが付与されています。
各アイコンには swiper-pagination-bullet というクラスが付き、現在のスライドを示す(アクティブな)アイコンには swiper-pagination-bullet-active というクラスが追加されています。
<div class="swiper-pagination swiper-pagination-clickable swiper-pagination-bullets"> <span class="swiper-pagination-bullet swiper-pagination-bullet-active" tabindex="0" role="button" aria-label="Go to slide 1"></span> <span class="swiper-pagination-bullet" tabindex="0" role="button" aria-label="Go to slide 2"></span> <span class="swiper-pagination-bullet" tabindex="0" role="button" aria-label="Go to slide 3"></span> </div>
以下はページネーションのデフォルトのスタイルの一部です。
.swiper-pagination { position: absolute; text-align: center; transition: 300ms opacity; transform: translate3d(0, 0, 0); z-index: 10; } .swiper-pagination-white { --swiper-pagination-color: #ffffff; } .swiper-pagination-black { --swiper-pagination-color: #000000; } /* Common Styles */ .swiper-pagination-fraction, .swiper-pagination-custom, .swiper-container-horizontal > .swiper-pagination-bullets { bottom: 10px; left: 0; width: 100%; } /* Bullets */ .swiper-pagination-bullet { width: 8px; height: 8px; display: inline-block; border-radius: 100%; background: #000; opacity: 0.2; /* アクティブ以外の場合の透明度 */ } button.swiper-pagination-bullet { border: none; margin: 0; padding: 0; box-shadow: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; } .swiper-pagination-clickable .swiper-pagination-bullet { cursor: pointer; } .swiper-pagination-bullet-active { opacity: 1; /* アクティブの場合の透明度 */ background: var(--swiper-pagination-color, var(--swiper-theme-color)); } /* Progress */ .swiper-pagination-progressbar { background: rgba(0, 0, 0, 0.25); position: absolute; } .swiper-pagination-progressbar .swiper-pagination-progressbar-fill { background: var(--swiper-pagination-color, var(--swiper-theme-color)); position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform: scale(0); transform-origin: left top; }
以下は bullets タイプのページネーションをカスタマイズする例です。
パラメータ renderBullet の関数の中で className を使用すると自動的にデフォルトのクラスが付与されます。また、(index + 1) で何番目のスライドかを表示できます。
<script> let swiper2 = new Swiper('#swiper02', { //スライダーのコンテナ要素の id で初期化 loop: true, pagination: { //ページネーションを表示 el: '.swiper-pagination', clickable: true, renderBullet: function (index, className) { return '<span class="' + className + '">' + (index + 1) + '</span>'; }, }, }); </script>
<div class="swiper-container" id="swiper02"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <div class="swiper-pagination"></div> </div>
デフォルトの bullets タイプのアイコンとは異なる見栄えにするので、アクティブとそうでない場合のそれぞれのスタイルを適宜(上書き変更する部分を)指定します。
#swiper02 .swiper-pagination-bullet { width: 20px; height: 20px; text-align: center; line-height: 20px; font-size: 12px; color:#000; background: #fff; } #swiper02 .swiper-pagination-bullet-active { color:#fff; background:#E59A0A; }
以下は fraction タイプ(スライド番号/総数)のページネーションを表示する例です。
<script> let mySwiper3 = new Swiper ('#swiper03', { loop: true, pagination: { el: '.swiper-pagination', type: 'fraction', //fraction タイプ }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>
<div class="swiper-container" id="swiper03"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <div class="swiper-pagination"></div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> </div>
ページネーションの文字の色を CSS で白に指定しています。
#swiper03 .swiper-pagination-fraction { color: #fff; }
以下は progressbar タイプのページネーションを表示する例です。
<script> let mySwiper4 = new Swiper ('#swiper04', { loop: true, pagination: { el: '.swiper-pagination', type: 'progressbar', //progressbar タイプ }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }) </script>
デフォルトのスタイルを上書きして、背景色と表示位置を変更しています。
#swiper04 .swiper-pagination-progressbar { background: rgba(0, 0, 0, 0.25); top: auto; /* 表示位置のデフォルトを変更 */ bottom: 0 ; /* 表示位置を下に */ } #swiper04 .swiper-pagination-progressbar .swiper-pagination-progressbar-fill { background: rgba(255,255,255,0.35); }
スクロールバー(Scrollbar)
スクロールバーを表示するには、HTML に swiper-scrollbar クラスの div 要素を記述します。
<div class="swiper-scrollbar"></div>
そして初期化の際にオプションの scrollbar を指定して必要なパラメータを設定します。
let mySwiper = new Swiper('.swiper-container', { scrollbar: { el: '.swiper-scrollbar', //スクロールバーの要素のセレクタ draggable: true, //スクロールバーをドラッグ可能にする }, });
初期化の際には以下のパラメータを指定することができます。
パラメータ | データ型 | デフォルト | 説明 |
---|---|---|---|
el | string | null | スクロールバーの要素の CSS セレクタまたは HTML 要素 |
hide | boolean | false | true を指定するとユーザーが操作を終了すると自動的に非表示になる |
draggable | boolean | false | true を指定するとユーザーがスクロールバーをドラッグしてスライドを操作できる |
以下はスクロールバーのデフォルトのスタイルの一部です。
/* Scrollbar */ .swiper-scrollbar { border-radius: 10px; position: relative; -ms-touch-action: none; background: rgba(0, 0, 0, 0.1); } .swiper-container-horizontal > .swiper-scrollbar { position: absolute; left: 1%; bottom: 3px; z-index: 50; height: 5px; width: 98%; } .swiper-container-vertical > .swiper-scrollbar { position: absolute; right: 3px; top: 1%; z-index: 50; width: 5px; height: 98%; }
以下は draggable: true を設定したスクロールバーとナビゲーションを表示する例です。
<div class="swiper-container" id="swiper05"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> <div class="swiper-scrollbar"></div> </div>
let mySwiper5 = new Swiper ('#swiper05', { scrollbar: { //スクロールバーを表示 el: '.swiper-scrollbar', draggable: true, }, navigation: { //ナビゲーションを表示 nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });
以下は初期化で loop: true を指定した場合のスクロールバーの表示例です。
ループを有効にすると、最初と最後のスライドが複製され、左端が最後のスライドの複製、右端が最初のスライドの複製に対応するようになり、前述の例とスクロールバーの表示が異なります。
自動再生(Autoplay)
自動的にスライドを開始(再生)させる場合は autoplay を設定します。
パラメータ | データ型 | デフォルト | 説明 |
---|---|---|---|
delay | number | 3000 | スライド間の間隔をミリ秒で指定。この値を指定しない場合は自動再生は無効になります。この設定と異なる値を個別のスライドに設定する場合は、スライドの要素(.swiper-slide)に data-swiper-autoplay 属性を設定してミリ秒の値を指定します。 |
stopOnLastSlide | boolean | false | true を指定すると、最後のスライドに達したら停止します。但し、ループモードでは無効です。 |
disableOnInteraction | boolean | true | ユーザが操作したら自動再生をストップさせる設定です。false を指定すると操作があっても自動再生を継続します。 |
reverseDirection | boolean | false | true を指定すると、逆方向に自動再生します。 |
以下はループモードでスライドの間隔を2秒(2000ミリ秒)に設定して自動再生するれいです。 data-swiper-autoplay を指定して、最後のスライドは5秒遅延させています。
デフォルトで disableOnInteraction は true なので、ナビゲーションやページネーションをクリックしたり、スワイプするとスライドは停止します。
let mySwiper6 = new Swiper ('#swiper06', { autoplay: { delay: 2000, }, loop: true, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });
<div class="swiper-container" id="swiper06"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> ・・・中略・・・ <div class="swiper-slide" data-swiper-autoplay="6000"><img src="images/sample_06.png" alt=""></div> </div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> <div class="swiper-pagination swiper-pagination-white"></div> </div>
最初のスライドに戻って停止
stopOnLastSlide のオプションの場合、自動再生後に最後のスライドで停止しますが、最初のスライドに戻った時点で停止する例です(動作を確認するにはページを再読み込みしてください)。
<div class="swiper-container" id="swiper07"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> </div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> </div>
最初のスライドに戻るためにループモードにします。
on で最後のスライドに達した際に発火されるイベント reachEnd に、autoplay の自動再生を停止するメソッド autoplay.stop() を実行する処理を登録します。
または、自動再生(autoplay)を無効(false)にする処理を登録しても同様の結果になります。this は Swiper のインスタンスです。
let mySwiper7 = new Swiper ('#swiper07', { autoplay: { //自動再生を有効に delay: 2000, }, loop: true, //ループモード navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, on: { reachEnd: function () { //reachEnd イベントに以下を登録 this.autoplay.stop(); //自動再生を停止 // または自動再生を解除 this.autoplay = false; }, }, });
メソッドやイベント
Autoplay のメソッドやイベントには以下のようなものがあります。
メソッド | 意味 |
---|---|
.autoplay.start(); | 自動再生を開始 |
.autoplay.stop(); | 自動再生を停止 |
イベント名 | 意味 |
---|---|
autoplayStart | 自動再生が開始されたときに発火 |
autoplayStop | 自動再生が停止されたときに発火 |
autoplay | 自動再生でスライドが遷移する(変わる)ときに発火 |
Lazy Loading(遅延読み込み)
遅延読み込み(Lazy Loading)を有効にするには、まず最初にマークアップを変更する必要があります。
- 画像要素や背景画像を指定する要素に swiper-lazy というクラスを追加します。
- img 要素の場合は src 属性の代わりに data-src 属性で画像を指定します。
- img 要素で srcset を使っている場合は srcset 属性の代わりに data-srcset 属性を指定します。
- 背景画像を指定している要素では、data-background で背景画像を指定します。
必要に応じて要素に指定するクラス名(swiper-lazy)やスライダーを実行中に付与されるクラス名を初期化の際に変更することができます。
.swiper-lazy-preloader を指定した div 要素を記述して、スライドに画像を読み込む際のアニメーションのプリローダースピナーを追加することもできます。.swiper-lazy-preloader を指定した div 要素は、画像の読み込み後に自動的に削除されます。
<div class="swiper-slide"> <img data-src="path/to/picture-1.jpg" class="swiper-lazy" /> <div class="swiper-lazy-preloader"></div><!-- プリローダースピナー(オプション)--> </div>
<div class="swiper-slide"> <img data-src="path/to/logo-small.png" data-srcset="path/logo/logo-large.png 2x" class="swiper-lazy" /> <div class="swiper-lazy-preloader"></div> </div>
<div class="swiper-slide"> <div data-background="path/to/picture-2.jpg" class="swiper-lazy"> <div class="swiper-lazy-preloader"></div> </div> </div>
<div class="swiper-slide swiper-lazy" data-background="path/to/picture-3.jpg"> <div class="swiper-lazy-preloader"></div> </div>
白色のスピナー画像のアニメーションを表示するには swiper-lazy-preloader-white クラスを追加します。
<!-- 白のスピナー .swiper-lazy-preloader-white を追加--> <div class="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
Lazy Loading のパラメータ
初期化の際に Lazy Loading のパラメータを指定します。
デフォルトでは preloadImages は true でスライダーの画像を全て先に読み込むので、preloadImages に false を指定します。また、lazy: true を指定して遅延読み込みを有効にします。
const mySwiper = new Swiper ('.swiper-container', { preloadImages: false, //画像の先読みを無効に lazy: true, // Lazy Loading を有効に ・・・その他のパラメータ(省略)・・・ })
画像のサイズにもよりますが、遅延読み込みを有効にすると画像を読み込む間スピナー画像のアニメーションが表示されます。loadPrevNext: true を指定すると、前後の画像を先に読み込んでおくことができるのでスピナー画像が表示されないようにできます(画像のサイズにもよるかと思います)。
const mySwiper = new Swiper ('.swiper-container', { preloadImages: false, //前後の画像を先に読み込んでおく lazy: { loadPrevNext: true, }, });
パラメータ | データ型 | デフォルト | 説明 |
---|---|---|---|
lazy | LazyOptions | boolean | 画像の遅延読み込みを有効にします。真偽値の true を指定するか、遅延読み込みのパラメータ(以下)を指定します。true を指定した場合は、遅延読み込みのパラメータのデフォルトが適用されます。 | |
LazyOptions | |||
checkInView | boolean | false | 最初のスライドに画像を遅延読み込みする前に、Swiper が表示されているかどうかを確認 |
elementClass | string | 'swiper-lazy' | 画像要素や背景画像を設定する要素に指定するクラス名(変更する場合に指定) |
loadOnTransitionStart | boolean | false | デフォルトではスライドアニメーションを実行後に遅延画像をロードしますが、スライドアニメーションの開始時に画像のロードを開始する場合は、このパラメーターを true にします。 |
loadPrevNext | boolean | false | true に設定すると、現在のスライド画像と最も近いスライド画像(1つ前と次)をプリロード(先読み込み)します。スライダーの画像が3枚の場合は、3枚ともプリロードされるので遅延読み込みになりません。 |
loadPrevNextAmount | number | 1 | 次/前のスライド画像をプリロードする数。slidesPerView の値以上にする必要があります |
loadedClass | string | 'swiper-lazy-loaded' | 遅延読み込みされた要素に付与されるクラス名(変更する場合に指定) |
loadingClass | string | 'swiper-lazy-loading' | 遅延読み込みしている要素に付与されるクラス名(変更する場合に指定) |
preloaderClass | string | 'swiper-lazy-preloadery' | プリローダーに指定するクラス名(変更する場合に指定) |
scrollingElement | CSSSelector | null | Dom7Array | HTMLElement | window | パラメータ checkInView のためのスクロールをチェックする要素 |
img 要素に data-src 属性を設定する場合の例
以下は img 要素に data-src 属性を設定して Lazy Loading を有効にする場合の例です。
data-src 属性に画像へのパスを指定し、swiper-lazy クラスを追加します。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img data-src="images/swiper_img_01.jpg" class="swiper-lazy" alt="" /> <div class="swiper-lazy-preloader"></div> </div> <div class="swiper-slide"> <img data-src="/images/swiper_img_02.jpg" class="swiper-lazy" alt="" /> <div class="swiper-lazy-preloader"></div> </div> ・・・中略・・・ <div class="swiper-slide"> <img data-src="images/swiper_img_08.jpg" class="swiper-lazy" alt="" /> <div class="swiper-lazy-preloader"></div> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- end of .swiper-container -->
.swiper-slide img { max-width: 100%; /* 画像をレスポンシブに */ }
この例の初期化では lazy: true を指定しているので、遅延読み込みのパラメータ(LazyOptions)の設定はデフォルトの値が適用されます。
そのため、初期状態では最初の1枚目の画像のみがロードされます。
<script> let mySwiper = new Swiper ('.swiper-container', { loop: true, preloadImages: false, //画像の先読みを無効に lazy: true, // 遅延読み込みを有効に pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>
背景画像を使っている場合の例
以下は背景画像を設定した要素をスライドさせる場合の例で、data-background 属性で背景画像を指定しています(CSS で指定する必要はありません)。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="swiper-lazy bg-slide-image" data-background="images/swiper_img_01.jpg"> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="swiper-lazy bg-slide-image" data-background="images/swiper_img_02.jpg"> <div class="swiper-lazy-preloader"></div> </div> </div> ・・・中略・・・ <div class="swiper-slide"> <div class="swiper-lazy bg-slide-image" data-background="images/swiper_img_08.jpg"> <div class="swiper-lazy-preloader"></div> </div> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- end of .swiper-container -->
この例では背景画像を指定する要素に bg-slide-image クラスを指定して背景画像のスタイルを設定しています。スライダーが1つだけ(ページ内でこのスライダーのみ)の場合や全て同じスタイルの場合などでは、swiper-lazy クラスに背景画像のスタイルを設定することもできます。
.swiper-container { max-width: 960px; } /* 背景画像のスタイル */ .bg-slide-image { width: 100%; height: 60vh; background-size: cover; background-position: center center; background-repeat: no-repeat; } .swiper-pagination-bullet { width: 10px; height: 10px; background: #fff; opacity: 0.5; } .swiper-pagination-bullet-active { opacity: 1; background: #fff; }
この例では loadPrevNext: true を指定して初期化しているので、現在の画像(swiper_img_01.jpg)とその前(swiper_img_08.jpg)と後(swiper_img_02.jpg)の3枚の画像が先読みされます。
<script> let mySwiper = new Swiper ('.swiper-container', { loop: true, //画像の先読みを無効に preloadImages: false, // 遅延読み込みを有効に lazy: { //1つ前と次のスライド画像をプリロード loadPrevNext: true, }, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>
thumbs サムネイル表示
thumbs パラメータを使ってサムネイルとメインのスライダーを連携することができます。
プラグインによってはこのような機能が用意されているものもありますが、Swiper の場合はスライダーの HTML を2つ記述して thumbs パラメータでサムネイルとメインのスライダーを連携させます。
以下がメインとサムネイルのスライダーのマークアップです。
初期化の際にそれぞれを特定できるように、.swiper-container の要素に ID やクラスを追加で指定します。
この例ではメインのスライダーには .main-slider、サムネイルのスライダーには .thumbs-slider というクラスを指定しています。
<!-- メインのスライダー--> <div class="swiper-container main-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- サムネイルのスライダー--> <div class="swiper-container thumbs-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> </div>
現在表示されているスライドに対応する(アクティブな)サムネイルには swiper-slide-thumb-active というクラスが追加されるので、そのクラスを使ってアクティブなサムネイルのスタイルを設定しています。
* { box-sizing: border-box; } .swiper-slide img { max-width: 100%; } /* サムネイルでアクティブなものには枠線を表示 */ .thumbs-slider .swiper-slide-thumb-active img { border: 4px solid #F6B5B6; } /* アクティブでないサムネイル */ .thumbs-slider .swiper-slide { opacity: 0.8; } /* アクティブなサムネイル */ .thumbs-slider .swiper-slide-thumb-active { opacity: 1; } .swiper-pagination-bullet-active { opacity: 1; background: #fff; }
サムネイルのスライダーのインスタンスをメインのスライダーの thumbs パラメータの swiper に指定する必要があるので、サムネイルのスライダーを最初に初期化しています。
また、サムネイルのスライダーの初期化では watchSlidesProgress と watchSlidesVisibility に true を設定します。
メインのスライダーの初期化では thumbs パラメータの swiper にサムネイルのスライダーのインスタンスを指定します。
<script> //サムネイルのスライダーの初期化 let mySwiperThumbs = new Swiper ('.thumbs-slider', { slidesPerView: 4, spaceBetween: 10, //各スライドの進行状況を監視 watchSlidesProgress: true, //ビューポートにあるスライドに表示クラスを追加 watchSlidesVisibility: true, //カーソルをデフォルトから grab に変更 grabCursor: true, }); //メインのスライダーの初期化 let mySwiperMain = new Swiper ('.main-slider', { navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, thumbs: { //サムネイルのスライダーを指定 swiper: mySwiperThumbs }, }); </script>
何故か両方(サムネイルとメイン)のスライダーのループを共に有効にすると、スライドの総数がサムネイルで表示するスライド数の倍数になっていると期待通りの動作になりませんでした。
例えば上記の例のように、スライドの総数が8でサムネイルで表示する数が4(slidesPerView: 4)の場合に両方のスライダーのループを有効にするとメインのスライドのナビゲーションを使って5枚目を表示する際にサムネイルのスライダーが連動せず6枚目で動くようような動作になってしまいます(サンプル)。
※メインのスライダーのみループを有効(サムネイルのループは無効)にすると問題なく動作します。
realIndexChange イベントで連携
thumbs パラメータを使ってサムネイルとメインのスライダーを連携する以外にも、サムネイルとメインのスライダーを連携することができます。
以下は realIndexChange イベントを使ってサムネイルとメインのスライダーを連携する例です。
realIndexChange はメインのスライダーではナビゲーションボタンをクリックした際に、サムネイルのスライダーでは slideToClickedSlide を設定することで任意のスライドをクリックした際に発火します。
この方法の場合、サムネイルのスライダーで slideToClickedSlide を設定しているので、サムネイルをドラッグしようとするとその時選択されたスライドが表示されてしまうこともあり、あまり使い勝手が良くないかも知れません。
HTML のマークアップは前述の例と同じです。
<!-- メインのスライダー--> <div class="swiper-container main-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- サムネイルのスライダー--> <div class="swiper-container thumbs-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> </div>
CSS は前述の例とは少し異なり、thumbs パラメータで連携していないので、.swiper-slide-thumb-active というクラスはアクティブなスライドに付与されません
そのため、この例ではサムネイルのアクティブなスライドは .thumbs-slider .swiper-slide-active で指定しています。
* { box-sizing: border-box; } .swiper-slide img { max-width: 100%; } /* メインのスライダーのアクティブでないものは不透明度を 0.6 に */ .main-slider .swiper-slide { opacity: 0.6; } /* メインのスライダーでアクティブなもの(現在表示されている)は不透明度を 1 に */ .main-slider .swiper-slide.swiper-slide-active { opacity: 1; } /* アクティブでないサムネイル */ .thumbs-slider .swiper-slide { opacity: 1; } /* アクティブなサムネイル */ .thumbs-slider2 .swiper-slide.swiper-slide-active { opacity: .6; } /* サムネイルでアクティブなものには枠線を表示 */ .thumbs-slider2 .swiper-slide.swiper-slide-active img { border: 4px solid #F6B5B6; } .swiper-pagination-bullet-active { opacity: 1; background: #fff; }
この例ではサムネイル及びメインのスライダーを realIndex(ループを考慮した実際のスライドのインデックス)が変わった際に発火されるイベント realIndexChange に登録しています。
realIndex が変わったら slideToLoop() メソッドを使って、渡されたインデックスに一致する realIndex を持つスライドに移行(スライド)します。
そして、サムネイルのスライダーでは任意のスライドをクリックするとそのスライドへ遷移するように slideToClickedSlide に true を指定しています。
また、centeredSlides に true を指定してアクティブなスライドを中央に配置するようにしています。
<script> //サムネイルのスライダーの初期化 let mySwiperThumbs = new Swiper ('.thumbs-slider', { loop: true, slidesPerView: 4, spaceBetween: 10, grabCursor: true, //アクティブなスライドを中央に配置 centeredSlides:true, //任意のスライドをクリックするとそのスライドへ遷移 slideToClickedSlide: true, }); //メインのスライダーの初期化 let mySwiperMain = new Swiper ('.main-slider', { loop: true, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, //1.3枚分表示 slidesPerView: 1.3, //アクティブなスライドを中央に配置(1.3枚分表示しているので) centeredSlides: true, spaceBetween: 10, }); //realIndex が変わった際に発火されるイベントに登録 mySwiperMain.on('realIndexChange', () => { // realIndex はループを考慮したアクティブなスライドの番号が入っている mySwiperThumbs.slideToLoop(mySwiperMain.realIndex); }); mySwiperThumbs.on('realIndexChange', () => { mySwiperMain.slideToLoop(mySwiperThumbs.realIndex); }); </script>
スライダーサンプル
Swiper を使ったスライダーのサンプルです。
基本的なスライダー
以下は HTML コンテンツをスライドにした基本的なスライダーのサンプルです。
画像だけではなく様々なコンテンツのスライダーを作成することができます。以下の例では画像の他にタイトルやキャプションなどもスライドにしています。
<div class="swiper-slide">〜 </div> にコンテンツを記述するだけです。
以下の例ではスタイルを適用しやすいように適宜クラスを指定した div 要素でコンテンツを囲んでいます(この例の場合は、不要なクラスもありますが)。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="slide-img"><img src="images/img_01.jpg" alt=""></div> <div class="slide-content"> <h1>Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div><!-- end of .swiper-slide --> <div class="swiper-slide"> <div class="slide-img"><img src="images/img_02.jpg" alt=""></div> <div class="slide-content"> <h2>Slide Title 02</h2> <p>Ipsa, quis ex repudiandae eum </p> <div class="caption">caption 02</div> </div> </div><!-- end of .swiper-slide --> <div class="swiper-slide"> <div class="slide-img"><img src="images/img_03.jpg" alt=""></div> <div class="slide-content"> <h3>Slide Title 03</h3> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div><!-- end of .swiper-slidet --> </div><!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div><!-- end of .swiper-container -->
画像以外のコンテンツは絶対配置(position: absolute)にして、配置しやすくしています。
.slide-img img { width: 100%; } .swiper-slide .slide-content h1, .swiper-slide .slide-content h2, .swiper-slide .slide-content h3 { position: absolute; top: 20%; left: 50%; transform: translate(-50%, -50%); color: #FFF; font-size: 30px; text-shadow: 2px 2px rgba(0,0,0,0.3); } .swiper-slide .slide-content p { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #FFF; text-shadow: .5px .5px rgba(0,0,0,0.6); margin: 0; padding: 0; font-size: 18px; } .swiper-slide .slide-content .caption { position: absolute; bottom: 30px; right: 30px; color: #FFF; font-size: 16px; background-color: rgba(0,127,127,0.5); padding: 3px 8px; }
また、タイトルと p 要素は中央に配置するようにしています。
要素を上下左右の中央に配置には、以下のように絶対配置を使って left と top のプロパティに50%のオフセットを指定し、translate(-50%、-50%)で幅と高さの半分の値を引き戻す方法があります。
.swiper-slide .slide-content p { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
初期化は画像のみのスライドと同じです。
<script> let mySwiper = new Swiper ('.swiper-container', { loop: true, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>
文字をアニメーションで表示
以下は CSS アニメーションを使ってタイトルの文字をアニメーションで表示する例です。
この例ではタイトル(h1, h2, h3 要素)の表示を CSS3 アニメーションで表示しています。
HTML と 初期化の JavaScript は前述の例と同じで、CSS に以下のアニメーションの記述を追加しているだけです。
異なる位置(top)と透明度(opacity)をキーフレームで設定してアニメーションで表示しています。
アニメーションを適用するのは、アクティブなスライドの要素なので「swiper-slide-active」クラスを使用します。
@keyframes fromBottom { 0% { top: 80%; opacity: 0; } 100% { top: 20%; opacity: 1; } } .swiper-slide-active h1, .swiper-slide-active h2, .swiper-slide-active h3 { animation: fromBottom .6s ease-in-out 0s 1 normal both; }
どのようなクラスが Swiper によって付与されているかはデベロッパーツールなどで確認することができます。
以下は Swiper によって出力される1枚目のスライドの部分の HTML です。
<div class="swiper-slide swiper-slide-active" data-swiper-slide-index="0" style="width: 500px;"> <div class="slide-img"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="slide-content"> <h1 class="noindex">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div>
例えば、この例の場合、ループモード(loop: true)にしているので Swiper によって、以下のような1つ前の画像が複製されています。
swiper-slide-duplicate というクラスが付与されているので複製されたスライドであることがわかります。
<div class="swiper-slide swiper-slide-duplicate swiper-slide-prev" data-swiper-slide-index="2" style="width: 500px;"> <div class="slide-img"><img src="images/swiper_img_03.jpg" alt=""></div> <div class="slide-content"> <h3 class="noindex">Slide Title 03</h3> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div>
前述の例では、要素に対してアニメーションを適用していましたが、以下のように要素にクラスを付与してそのクラスにアニメーションを適用したほうが管理しやすくなると思います。
アニメーションを適用する要素に個別のアニメーションのクラス(例 .from_top)を指定しておきます。
<div class="swiper-slide"> <div class="slide-img"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="slide-content"> <h1 class="from_top">Slide Title 01</h1><!-- アニメーション適用 --> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div> <div class="swiper-slide"> <div class="slide-img"><img src="images/swiper_img_02.jpg" alt=""></div> <div class="slide-content"> <h2 class="from_left">Slide Title 02</h2><!-- アニメーション適用 --> <p class="from_right">Ipsa, quis ex repudiandae eum </p><!--アニメーション適用--> <div class="caption">caption 02</div> </div> </div> <div class="swiper-slide"> <div class="slide-img"><img src="images/swiper_img_03.jpg" alt=""></div> <div class="slide-content"> <h3 class="from_bottom">Slide Title 03</h3><!-- アニメーション適用 --> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div>
この例では以下のような4つの異なるアニメーションを用意しています。
@keyframes fromTop { 0% { top: 0%; opacity: 0; } 100% { top: 20%; opacity: 1; } } @keyframes fromBottom { 0% { top: 80%; opacity: 0; } 100% { top: 20%; opacity: 1; } } @keyframes fromleft { 0% { left: 0%; opacity: 0; } 100% { left: 50%; opacity: 1; } } @keyframes fromRight { 0% { left: 100%; opacity: 0; } 100% { left: 50%; opacity: 1; } } /* .from_top を指定した要素のアニメーション */ .swiper-slide-active .from_top { animation: fromTop .6s ease-in-out 0s 1 normal both; } /* .from_bottom を指定した要素のアニメーション */ .swiper-slide-active .from_bottom { animation: fromBottom .6s ease-in-out 0s 1 normal both; } /* .from_left を指定した要素のアニメーション */ .swiper-slide-active .from_left { animation: fromleft .6s ease-in-out 0s 1 normal both; } /* .from_right を指定した要素のアニメーション */ .swiper-slide-active .from_right{ animation: fromRight .6s ease-in-out .5s 1 normal both; }
画像も文字と同じように追加してアニメーションを設定することができます。
<div class="swiper-slide"> <div class="slide-img"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="slide-content"> <h1 class="from_top noindex">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> <!-- 追加した画像の HTML --> <div class="animation_img from_right2"><img src="images/swiper_img_04.jpg" alt=""></div> </div> </div>
.swiper-slide .slide-content .animation_img { position: absolute; bottom: 30px; left: 30px; max-width: 120px; border-radius: 50%; } .swiper-slide .slide-content .animation_img img { border-radius: 50%; border: 2px solid #fff; } @keyframes fromRight2 { 0% { left: 200px; opacity: 0; } 100% { left: 30px; opacity: 1; } } .swiper-slide-active .from_right2 { animation: fromRight2 .3s ease-in-out .6s 1 normal both; }
画像にアニメーション
文字と同様、画像にも CSS のアニメーションを簡単に付けることができます。
以下は前述の文字のアニメーションのサンプルに画像のアニメーションを追加したものです。
「Swiper+CSSのみ!ズームアップしながらフェードインで切り替わるスライダーの実装方法」を参考にさせていただきました。
HTML では、アニメーションを適用する画像の要素にアニメーションのクラス(.zoom, .translate1, .translate2)を指定します。
この例では、画像を囲む div 要素(.slide-img)にクラスを追加しています。
<div class="swiper-slide"> <!-- アニメーション用クラス(以下は .zoom)を指定 --> <div class="slide-img zoom"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="slide-content"> <h1 class="from_top">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div> <div class="swiper-slide"> <div class="slide-img translate1"><img src="images/swiper_img_02.jpg" alt=""></div> <div class="slide-content"> <h2 class="from_left">Slide Title 02</h2> <p class="from_right">Ipsa, quis ex repudiandae eum </p> <div class="caption">caption 02</div> </div> </div> <div class="swiper-slide"> <div class="slide-img translate2"><img src="images/swiper_img_03.jpg" alt=""></div> <div class="slide-content"> <h3 class="from_bottom">Slide Title 03</h3> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div>
この例では transform を使った3つのアニメーションを用意しています。
translate() を使う場合は、画像が移動するため画像の位置がずれてしまうので、scale() を使って画像を移動する分(以下の場合はおよその値)だけあらかじめ大きくしてあります。
@keyframes zoom { 0% { transform: scale(1); } 100% { transform: scale(1.1); } } .swiper-slide-active .zoom img { animation: zoom 6s linear 0s 1 normal both; } @keyframes translate1 { 0% { transform: scale(1.07) translate(0,0); } 100% { transform: scale(1.07) translate(3%, 2%); } } .swiper-slide-active .translate1 img { animation: translate1 6s linear 0s 1 normal both; } @keyframes translate2 { 0% { transform: scale(1.05) translate(1%,2%); } 100% { transform: scale(1.1) translate(-2%, -3%); } } .swiper-slide-active .translate2 img { animation: translate2 6s linear 0s 1 normal both; }
背景画像にアニメーション
画像要素(img)ではなく div 要素に背景画像(background-image)を指定する例です。
画像要素を使った前述の例とほぼ同様のことができますが、サイズの指定など少し面倒かも知れません。アニメーションなどは同じですが、このページの例の場合は画像の縦横比が異なります。
この例の場合、背景画像にアニメーションを適用するので、.swiper-slide に背景画像を指定するのではなく、その子要素の .slide-img に背景画像を指定しています(そうしないと文字なども一緒にアニメーションが適用されてしまうため)。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <!-- img 要素から背景画像(background-image)に変更--> <div class="slide-img zoom" style="background-image: url('images/swiper_img_01.jpg')"></div> <div class="slide-content"> <h1 class="from_top">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div> <div class="swiper-slide"> <!-- img 要素から背景画像(background-image)に変更--> <div class="slide-img translate1" style="background-image: url('images/swiper_img_02.jpg')"></div> <div class="slide-content"> <h2 class="from_left">Slide Title 02</h2> <p class="from_right">Ipsa, quis ex repudiandae eum </p> <div class="caption">caption 02</div> </div> </div> <div class="swiper-slide"> <!-- img 要素から背景画像(background-image)に変更--> <div class="slide-img translate2" style="background-image: url('images/swiper_img_03.jpg')"></div> <div class="slide-content"> <h3 class="from_bottom">Slide Title 03</h3> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div> </div><!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div><!-- end of .swiper-container -->
また、表示するコンテンツを以下のように .slide-img と .zoom を指定した div 要素で囲むこともできますが、その場合、コンテンツも zoom などのアニメーションの対象になります。
スライダーの内容によっては、以下のように囲んだ方が良い場合もあるかと思います。
<div class="swiper-slide"> <div class="slide-img zoom" style="background-image: url('images/swiper_img_01.jp')"> <div class="slide-content"> <h1 class="from_top">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div><!-- end of .slide-img.zoom(コンテンツを囲む) --> </div>
CSS では背景画像(height や background-size など)のプロパティを設定する必要があります。
/* .slide-img の背景画像の設定を追加 */ .slide-img { /* 小画面 */ height: 300px; background-size: cover; background-position: center center; background-repeat: no-repeat; overflow:visible; } @media only screen and (min-width:651px) { /* 中画面 */ .slide-img { height: 450px; } } @media only screen and (min-width:961px) { /* 大画面 */ .slide-img { height: 593px; } } /* 画像のアニメーション (変更部分にコメントで記載)*/ @keyframes zoom { 0% { transform: scale(1); } 100% { transform: scale(1.1); } } .swiper-slide-active .zoom { /* img を削除 */ animation: zoom 6s linear 0s 1 normal both; } @keyframes translate1 { 0% { transform: scale(1.07) translate(0,0); } 100% { transform: scale(1.07) translate(3%, 2%); } } .swiper-slide-active .translate1 { /* img を削除 */ animation: translate1 6s linear 0s 1 normal both; } @keyframes translate2 { 0% { transform: scale(1.05) translate(1%,2%); } 100% { transform: scale(1.1) translate(-2%, -3%); } } .swiper-slide-active .translate2 { /* img を削除 */ animation: translate2 6s linear 0s 1 normal both; }
background-position を使ったアニメーション
今までの例の場合、水平方向へのアニメーションは translate() を使用していましたが、その場合、位置がずれるので同時に scale() も使ってずれないように調整していました。
以下は background-position の値を変更するアニメーションを使う例です。但し、表示する画像の幅や高さを調整する必要があります。
以下はこの例の HTML ですが前述の例との違いはアニメーションのクラス名が変わっていることだけです。
<div class="swiper-slide"> <!-- アニメーションのクラス名(posChg1 など)が変わっているのみ --> <div class="slide-img posChg1" style="background-image: url('images/swiper_img_01.jpg')"></div> <div class="slide-content"> <h1 class="from_top">Slide Title 01</h1> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption">caption 01</div> </div> </div> <div class="swiper-slide"> <div class="slide-img posChg2" style="background-image: url('images/swiper_img_02.jpg')"></div> <div class="slide-content"> <h2 class="from_left">Slide Title 02</h2> <p class="from_right">Ipsa, quis ex repudiandae eum </p> <div class="caption">caption 02</div> </div> </div> <div class="swiper-slide"> <div class="slide-img posChg3" style="background-image: url('images/swiper_img_03.jpg')"></div> <div class="slide-content"> <h3 class="from_bottom">Slide Title 03</h3> <p>Ullam rerum quasi libero esse </p> <div class="caption">caption 03</div> </div> </div>
CSS では表示される領域が画像の幅より小さくなるように調整しています。
表示される領域と画像の幅が同じ(または領域の方が大きい)場合、以下の background-position を使ったアニメーションは意味がありません(動かないです)。
.swiper-container{ max-width: 720px; /* 最大幅を設定(背景画像より小さく設定) */ } .slide-img { /* 画像の幅が表示される領域(スライダー)の幅より小さくなるように高さで(割合を)調整 */ height: 500px; background-size: cover; background-position: center center; background-repeat: no-repeat; overflow:visible; } /* background-position を使ったアニメーションの設定 */ @keyframes posChg1 { 0% { background-position: 100% center; /*background-position: right center; と同じ*/ } 100% { background-position: center center; } } .swiper-slide-active .posChg1 { animation: posChg1 6s linear 0s 1 normal both; } @keyframes posChg2 { 0% { background-position: 70% center; } 100% { background-position: 30% center; } } .swiper-slide-active .posChg2 { animation: posChg2 6s linear 0s 1 normal both; } @keyframes posChg3 { 0% { background-position: center center; } 100% { background-position: 100% center; /*background-position: right center; と同じ*/ } } .swiper-slide-active .posChg3 { animation: posChg3 6s linear 0s 1 normal both; }
以下は垂直方向のアニメーションの例です。スライダーの高さを小さくしています。
/* 変更部分 */ .swiper-container{ max-width: 720px; } .slide-img { /* 表示される領域(スライダー)の高さが画像の高さより小さくなるように調整 */ height: 360px; background-size: cover; background-position: center center; background-repeat: no-repeat; overflow:visible; } /* 垂直方向のアニメーション background-position の2つ目のパラメータで指定 */ @keyframes posChg1 { 0% { background-position: center top; /*background-position: center 0%; と同じ*/ } 100% { background-position: center center; } } .swiper-slide-active .posChg1 { animation: posChg1 4s linear 0s 1 normal both; } @keyframes posChg2 { 0% { background-position: center 70%; } 100% { background-position: center 30%; } } .swiper-slide-active .posChg2 { animation: posChg2 6s linear 0s 1 normal both; } @keyframes posChg3 { 0% { background-position: center center; } 100% { background-position: center 100%; /*background-position: center bottom; と同じ*/ } } .swiper-slide-active .posChg3 { animation: posChg3 2s linear 0s 1 normal both; }
画面幅によりグリッド/スライド表示
画面幅が一定(この例では 961px)以上の場合はグリッドで表示し、スマホなど画面幅が狭い場合はスライドで表示する例です。
「レスポンシブ対応でjQuery不要の高機能スライダー Swiper(PC時はグリッド表示、スマホ時にスライドにする)」を参考にさせていただきました。
以下が HTML です。Swiper の構造を使ってマークアップしています。
<div class="container"> <div class="swiper-container" id="mySlider"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_04.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_05.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_06.png" alt=""></div> </div><!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> </div><!-- end of .swiper-container --> </div><!-- end of .container -->
画面幅が 961px 以上の場合は Flexbox を使ってレイアウトし、また、ナビゲーションボタンやページネーションは display: none で非表示にしています。
.container { margin: auto; max-width: 1400px; } .swiper-slide img { width: 100%; height: auto; } @media(min-width: 961px) { .swiper-wrapper { display: flex; flex-wrap: wrap; justify-content: center; } .swiper-slide { max-width: 400px; padding: 0 5px; } .swiper-button-prev, .swiper-button-next, .swiper-pagination { display: none; } }
初期化の関数 initSwiper() を作成して、画面幅が 961px 未満で且つ Swiper のインスタンスが生成されていない場合は初期化を実行してスライダーを表示します。
画面幅が 961px 以上で且つ Swiper のインスタンスが有効であれば(存在すれば)、.destroy() メソッドでインスタンスを破棄し、変数に null を代入します(判定用)。
destroy() は2つのパラメータを取り、1つ目(deleteInstance)はインスタンスを削除するかどうかの真偽値、2つ目(cleanStyles)はスライダーの要素(スライド、ラッパー、コンテナ)から不要になったスタイルなどを削除するかの真偽値です。両方ともデフォルトは true なので以下の場合、省略可能です。
また、resize イベントに登録して、画面幅に変更があった場合は、初期化の関数 initSwiper() を実行するようにしています。
<script> let mySwiperX; //Swiperインスタンスを格納する変数の宣言 let screenWidth; //画面幅の値を格納する変数の宣言 let swiperElement = document.getElementById("mySlider"); //コンテナ要素 let options = { //スライダーの初期化のオプション loop: true, centeredSlides : true, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, slidesPerView: 1, spaceBetween: 0, breakpoints: { 641: { slidesPerView: 2, spaceBetween: 10 }, } }; function initSwiper() { if(swiperElement){ //コンテナ要素があれば screenWidth = window.innerWidth; //画面幅を取得 if(screenWidth < 961 && !mySwiperX ) { mySwiperX = new Swiper('#mySlider', options); //スライダーの初期化 } else if (screenWidth >= 961 && mySwiperX ) { mySwiperX.destroy(true, true); //スライダーを破棄 mySwiperX = null; } } } initSwiper(); window.addEventListener('resize',initSwiper); </script>
その他のサンプル
Flexbox を使ったサンプル
6枚の画像を1つのスライドに表示する例です。実用的かどうかは定かではありません。
この例の場合、指定する画像のサイズ及び画面幅により1行に表示される数が決まるので適宜調整します。
Flexbox を使ってスライドを中央に配置します(もっと良い方法があるかも知れません)。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/sample_01.png" alt=""> <img src="images/sample_02.png" alt=""> <img src="images/sample_03.png" alt=""> <img src="images/sample_04.png" alt=""> <img src="images/sample_05.png" alt=""> <img src="images/sample_06.png" alt=""> </div> <div class="swiper-slide"> <img src="images/sample_01.png" alt=""> ・・・中略・・・ <img src="images/sample_06.png" alt=""> </div> <div class="swiper-slide"> <img src="images/sample_01.png" alt=""> ・・・中略・・・ <img src="images/sample_06.png" alt=""> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-pagination"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- end of .swiper-container.flex -->
.swiper-slide { /* 中央寄せするための設定 */ display: flex; flex-wrap: wrap; justify-content: center; } .swiper-slide img { width: 100%; max-width: 160px; /* 画面幅とこの幅により表示枚数が決まる */ margin: 10px; } .swiper-pagination { /* pagination の位置調整 */ bottom: -5px; } .swiper-container{ /* pagination の位置調整 */ padding-bottom: 20px; }
let swiper = new Swiper('.swiper-container', { pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });
グリッドを使ったサンプル
Bootstrap のグリッドを使って画面幅により異なる行(列)の画像を表示する例です。
前述の例と同じく6枚の画像を1つのスライドに表示する例ですが、こちらの方が制御しやすいかと思います。
Bootstrap の CSS を読み込む必要があります。
Bootstrap のグリッドを使うので、必要に応じて container クラスを指定し(以下の例ではスライダのコンテナに指定)、<div class="row">〜</div> に画像を配置してレスポンシブグリッドのクラス(ol-lg-4 など)を指定します。
<head> <meta charset="utf-8"> ・・・中略・・・ <link rel="stylesheet" href="bootstrap.min.css"><!-- bootstrap の読み込み --> <link rel="stylesheet" href="swiper.min.css"> </head> ・・・中略・・・ <div class="swiper-container container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="row"> <div class="col-6 col-lg-4"><img src="images/sample_01.png" alt=""></div> <div class="col-6 col-lg-4"><img src="images/sample_02.png" alt=""></div> <div class="col-6 col-lg-4"><img src="images/sample_03.png" alt=""></div> <div class="col-6 col-lg-4"><img src="images/sample_04.png" alt=""></div> <div class="col-6 col-lg-4"><img src="images/sample_05.png" alt=""></div> <div class="col-6 col-lg-4"><img src="images/sample_06.png" alt=""></div> </div> </div> <div class="swiper-slide"> <div class="row"> <div class="col-6 col-lg-4"><img src="images/sample_01.png" alt=""></div> ・・・中略・・・ <div class="col-6 col-lg-4"><img src="images/sample_06.png" alt=""></div> </div> </div> <div class="swiper-slide"> <div class="row"> <div class="col-6 col-lg-4"><img src="images/sample_01.png" alt=""></div> ・・・中略・・・ <div class="col-6 col-lg-4"><img src="images/sample_06.png" alt=""></div> </div> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-pagination"></div> <div class="swiper-button-prev swiper-button-black"></div> <div class="swiper-button-next swiper-button-black"></div> </div> <!-- end of .swiper-container.flex -->
.swiper-slide img { width: 100%; margin: 10px 0; }
let swiper= new Swiper('.swiper-container', { pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });
data 属性を使ってパラメータを設定
スライダーを初期化する際にオプションをパラメータを使って設定することができますが、スライダーごとに初期化の記述をするのはスライダーの数が多くなると大変です。
以下は HTML の data 属性を使ってマークアップによりオプションを設定する初期化の例です。
以下のスクリプトを記述するか読み込んだページでは、スライダーの HTML を記述して、必要に応じて data-* 属性でパラメータを指定してスライダーを表示することができます(個々にスライダーを初期化する必要がありません)。
一部のパラメータしか設定していないので、必要に応じてパラメータを追加します。
最初に getElementsByClassName() を使ってそのページにあるクラス swiper-container が指定されたスライダーの要素を変数 sliderElems に取得しています。そして for...of 文でそれぞれのスライダーの要素に設定された data 属性を getAttribute() で取得し、それらの値をスライダーのパラメータに設定しています。
この例の場合、.swiper-container が指定されたスライダーを全て対象にしていますが、対象のスライダーに特定のクラスを指定するなどして、getElementsByClassName() の引数を変更すれば対象を限定することができます。セレクタが複雑になるようであれば、querySelectorAll() などを使うと良いと思います。
data 属性が設定されていない場合は初期値(デフォルト)を設定します。また、getAttribute() で取得する値は文字列なので 'true' などは真偽値に変換します。数値の値はパラメータに設定する際に parseInt() や parseFloat() で数値に変換しています。
自動再生に関しては、data-autoplay が設定されていない場合は、値に 999999999 を設定して 999999999 ミリ秒の間隔で自動再生するようにして、実質的には自動再生なしのようにしています。
※自動再生のパラメータ autoplay に関しては、Swiper 自体が data-swiper-autoplay という属性を用意しているのでそちらを使う方法もあります。Swiper が用意している data-* 属性は data-swiper-xxxx という名前がついています。
バージョン7の場合はスライダーのコンテナ要素のクラスを swiper-container から swiper に変更し、getElementsByClassName() の引数 'swiper-container' を 'swiper' に変更します。
(修正)data-* 属性の名前にキャメルケースを使用していたのをハイフンを使った小文字に修正しました。
//swiper-container クラスを指定した要素(スライダーのコンテナ)を取得 const sliderElems = document.getElementsByClassName('swiper-container'); //取得した要素が1以上であればそれぞれの要素に対して以下を実行 if(sliderElems && sliderElems.length > 0) { for ( let element of sliderElems ) { //data 属性の値をパラメータの値として使用する変数に格納 let elementSpeed = element.getAttribute('data-speed'), elementDirection = element.getAttribute('data-direction'), elementAutoPlay = element.getAttribute('data-autoplay'), elementLoop = element.getAttribute('data-loop'), elementEffect = element.getAttribute('data-effect'), elementSlidesPerView = element.getAttribute('data-slides-per-view'), elementSlidesPerGroup = element.getAttribute('data-slides-per-group'), elementSpaceBetween = element.getAttribute('data-space-between'), elementCenteredSlides = element.getAttribute('data-centered-slides'); //data 属性が設定されていない場合は初期値(デフォルト)を設定及び型を変換 if (!elementSpeed) { elementSpeed = 300; } if (!elementDirection) { elementDirection = 'horizontal'; } //data-autoplay が設定されていれば値を数値に変換し、設定されていなければ大きな値を設定 if (elementAutoPlay) { elementAutoPlay = parseInt(elementAutoPlay); } else { elementAutoPlay = 999999999; } //真偽値の場合は文字列から真偽値に変換 if (elementLoop == 'true') { elementLoop = true; } else { elementLoop = false; } if (!elementEffect) { elementEffect = 'slide'; } if (!elementSlidesPerView) { elementSlidesPerView = 1; } if (elementCenteredSlides == 'true') { elementCenteredSlides = true; } else { elementCenteredSlides = false; } if (!elementSlidesPerGroup) { elementSlidesPerGroup = 1; } if (!elementSpaceBetween) { elementSpaceBetween = 0; } //上記パラメータを使って Swiper を初期化 let swiperSlider = new Swiper(element, { direction: elementDirection, speed: parseInt(elementSpeed), autoplay: { delay: elementAutoPlay }, loop: elementLoop, effect: elementEffect, slidesPerView: parseFloat(elementSlidesPerView), centeredSlides: elementCenteredSlides, slidesPerGroup: parseInt(elementSlidesPerGroup), spaceBetween: parseInt(elementSpaceBetween), pagination: { el: '.swiper-pagination', //ページネーションの要素 type: 'bullets', //ページネーションの種類 clickable: true, //クリックに反応させる }, navigation: { nextEl: '.swiper-button-next', //「次へボタン」要素の指定 prevEl: '.swiper-button-prev', //「前へボタン」要素の指定 }, scrollbar: { el: '.swiper-scrollbar', //要素の指定 }, }); } }
上記のコードで初期化すると以下のように data 属性を使ってパラメータを指定することができます。
以下は data 属性を設定していないので、デフォルトが適用されます。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_02.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_03.jpg" alt=""></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>
以下は data-direction に vertical を設定して垂直方向にスライドする例です。data-direction="vertical" を指定した場合は、スタイルで height または max-height を設定する必要があります。
また、data-loop="true" も指定してスライドをループモードにしています(最後に達したら先頭に戻る)。
<div class="swiper-container" data-loop="true" data-direction="vertical" style="max-height: 370px;"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_02.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_03.jpg" alt=""></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>
以下は data-effect="cube" を指定し、スライドのスピードを data-speed="1000" で指定しています。
<div class="swiper-container" data-loop="true" data-effect="cube" data-speed="1000"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/swiper_img_01.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_02.jpg" alt=""></div> <div class="swiper-slide"><img src="images/swiper_img_03.jpg" alt=""></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>
以下は data-effect="coverflow" を指定し、data-slides-per-view="2" で表示枚数を2枚にし、data-centered-slides="true" で中央寄せにしています。
<div class="swiper-container" data-effect="coverflow" data-slides-per-view="2" data-centered-slides="true" data-loop="true"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_04.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_05.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_06.png" alt=""></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>
以下は data-autoplay="5000" で5秒間隔で自動再生し、表示枚数と同時にスライドする数を data-slides-per-view と data-slides-per-group で設定しています。
また、data-space-between="5" で画像の間隔を 5px に指定しています。
<div class="swiper-container" data-autoplay="5000" data-slides-per-view="2" data-loop="true" data-slides-per-group="2" data-space-between="5"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="images/sample_01.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_02.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_03.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_04.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_05.png" alt=""></div> <div class="swiper-slide"><img src="images/sample_06.png" alt=""></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>
遅延読み込みにも対応
以下は遅延読み込み(Lazy Loading)にも対応するようにした例です。
swiper-lazy クラスを指定した要素があれば、遅延用見込みをするように(lazy を true、preloadImages を false に)しています。data-load-prev-next に true が指定されていれば、前後の画像を先に読みするように loadPrevNext を true にします。
また、autoplay が有効で且つループモードで data-stop-at-first-slide 属性に true が指定されていれば、先頭のスライドに戻ったら自動的に停止するようにしています。ループモードでない場合は、最後のスライドで停止します(autoplay パラメータの stopOnLastSlide と同じ)。
バージョン7の場合はスライダーのコンテナ要素のクラスを swiper-container から swiper に変更し、2行目の getElementsByClassName() の引数 'swiper-container' を 'swiper' に変更します。
//swiper-container クラスを指定した要素を全て取得 const sliderElems = document.getElementsByClassName('swiper-container'); //取得した要素が1以上であればそれぞれの要素に対して以下を実行 if(sliderElems && sliderElems.length > 0) { for ( let element of sliderElems ) { //data 属性の値をパラメータの値として使用する変数に格納 let elementSpeed = element.getAttribute('data-speed'), elementDirection = element.getAttribute('data-direction'), elementAutoPlay = element.getAttribute('data-autoplay'), elementLoop = element.getAttribute('data-loop'), elementEffect = element.getAttribute('data-effect'), elementSlidesPerView = element.getAttribute('data-slides-per-view'), elementSlidesPerGroup = element.getAttribute('data-slides-per-group'), elementSpaceBetween = element.getAttribute('data-space-between'), elementCenteredSlides = element.getAttribute('data-centered-slides'), elementLoadPrevNext = element.getAttribute('data-load-prev-next'), elementStopAtFirstSlide = element.getAttribute('data-stop-at-first-slide'), elementLazyLoad = false, slidePreloadImages = true; //.swiper-lazy(遅延読み込み)を指定している要素 let swiperLazyElems = element.querySelectorAll('.swiper-lazy'); if(swiperLazyElems && swiperLazyElems.length !==0 ) { //.swiper-lazy を指定している要素が存在すれば true に変更 elementLazyLoad = true; } //lazyload が指定されている(.swiper-lazy を指定した要素がある)場合 if(elementLazyLoad) { //data-load-prev-next の値を文字列から真偽値に変換 if (elementLoadPrevNext === 'true') { elementLoadPrevNext = true; } else { elementLoadPrevNext = false; } //elementLoadPrevNext が指定されていれば前後の画像を先に読み込んでおく elementLazyLoad = elementLoadPrevNext ? { loadPrevNext: true,} : true; //画像全体の先読みは無効に slidePreloadImages = false; } //data 属性が設定されていない場合は初期値(デフォルト)を設定及び型を変換 if (!elementSpeed) { elementSpeed = 300; } if (!elementDirection) { elementDirection = 'horizontal'; } //data-autoplay が設定されていれば値を数値に変換し、設定されていなければ大きな値を設定 if (elementAutoPlay) { elementAutoPlay = parseInt(elementAutoPlay); } else { elementAutoPlay = 999999999; } //真偽値の場合は文字列から真偽値に変換 if (elementLoop === 'true') { elementLoop = true; } else { elementLoop = false; } if (!elementEffect) { elementEffect = 'slide'; } if (!elementSlidesPerView) { elementSlidesPerView = 1; } if (elementCenteredSlides === 'true') { elementCenteredSlides = true; } else { elementCenteredSlides = false; } if (!elementSlidesPerGroup) { elementSlidesPerGroup = 1; } if (!elementSpaceBetween) { elementSpaceBetween = 0; } //上記パラメータを使って Swiper を初期化 let mySwiper = new Swiper(element, { direction: elementDirection, speed: parseInt(elementSpeed), autoplay: { delay: elementAutoPlay }, loop: elementLoop, effect: elementEffect, slidesPerView: parseFloat(elementSlidesPerView), centeredSlides: elementCenteredSlides, slidesPerGroup: parseInt(elementSlidesPerGroup), spaceBetween: parseInt(elementSpaceBetween), //画像の先読み(遅延読み込みの場合は false) preloadImages: slidePreloadImages, //遅延読み込み lazy: elementLazyLoad, pagination: { el: '.swiper-pagination', //ページネーションの要素 type: 'bullets', //ページネーションの種類 clickable: true, //クリックに反応させる }, navigation: { nextEl: '.swiper-button-next', //「次へボタン」要素の指定 prevEl: '.swiper-button-prev', //「前へボタン」要素の指定 }, scrollbar: { el: '.swiper-scrollbar', //要素の指定 }, }); if (elementStopAtFirstSlide === 'true') { elementStopAtFirstSlide = true; } else { elementStopAtFirstSlide = false; } //自動再生とループモードが有効でdata-stop-at-first-slideがtrueなら最初のスライドに戻ったら停止 //ループモードでない場合は、最後のスライドで停止 if(elementAutoPlay !== 999999999 && elementStopAtFirstSlide) { mySwiper.on('reachEnd', function () { this.autoplay.stop(); //自動再生を停止 }); } } }
以下は上記スクリプトを使って、背景画像を使ったスライドで遅延読み込みを有効(.swiper-lazy を指定)にして前後の画像のみ先読みし、自動再生とループモードを有効にして、最初のスライドに戻ったら停止するようにしています。
<div class="swiper-container" data-autoplay="3000" data-loop="true" data-speed="500" data-load-prev-next="true" data-stop-at-first-slide="true"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="swiper-lazy bg-slide-image" data-background="images/swiper_img_01.jpg"> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="swiper-lazy bg-slide-image" data-background="images/swiper_img_02.jpg"> <div class="swiper-lazy-preloader"></div> </div> </div> ・・・中略・・・ </div> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev swiper-button-white"></div> <div class="swiper-button-next swiper-button-white"></div> </div>
サムネイル表示に対応
以下は thumbs パラメータを使ったサムネイルとメインのスライダーを HTML の data 属性を使ってマークアップするようにした例です。
但し、前述の2つの例の通常のスライダーと併用するには、少し工夫が必要です。
前述の2つの例では、.swiper-container が指定されたスライダーの要素を全て取得して処理するようにしているので、以下を併用する場合は、サムネイルとメインのスライダーを除外する必要があります。または、通常のスライダーには何らかのクラスを指定して、そのスライダーを対象に処理するようにします。
以下の例では、.thumbs-slider を指定したスライダーをサムネイル用スライダー、.main-slider を指定したスライダーをメイン用スライダーとしています。
そのため、前述の通常のスライダー用のスクリプトと併用する場合は、例えば以下のように .thumbs-slider と .main-slider を除外するなどします。
//取得するスライダーの要素から .thumbs-slider と .main-slider を除外 const sliderElems = document.querySelectorAll('.swiper-container:not(.thumbs-slider, .main-slider)'); if(sliderElems && sliderElems.length > 0) { for ( let element of sliderElems ) { //data 属性の値をパラメータの値として使用する変数に格納 let elementSpeed = element.getAttribute('data-speed'), ・・・以下省略・・・
以下はサムネイルとメインのスライダーを HTML でマークアップして data-* 属性を指定することで(個々のスライダーを初期化せずに)表示できるようにする JavaScript の例です。
サムネイルのスライダーでは、data-slides-per-view 属性を指定しないとデフォルトでは4枚表示されます。その他必要に応じてパラメータを data-* 属性を使って指定します。
以下のスクリプトを読み込んで HTML でサムネイルとメインのスライダーをマークアップすれば、個々のスライダーを初期化せずに、同じページに複数のサムネイルとメインのスライダーを表示することができます。
前述の例同様、data-* 属性でパラメータを指定することができますが、パラメータによっては、期待通りに動作しないかも知れません(全てのパラメータを試して確認していません)。
//main-slider クラスを指定した要素を取得 const mainSliders = document.getElementsByClassName('main-slider'); //thumbs-slider クラスを指定した要素を取得 const thumbsSliders = document.getElementsByClassName('thumbs-slider'); //サムネイルのスライダーのインスタンスを格納する配列 const mySwiperThumbsArray = []; //サムネイルとメインのスライダーの数が同じであれば、以下を実行 if(mainSliders && thumbsSliders && mainSliders.length > 0 && thumbsSliders.length > 0 && mainSliders.length === thumbsSliders.length) { //サムネイルの各スライダーへの処理 for ( let i=0; i<thumbsSliders.length; i++ ) { //data 属性の値をパラメータの値として使用する変数に格納 let dataSpeed = thumbsSliders[i].getAttribute('data-speed'), dataDirection = thumbsSliders[i].getAttribute('data-direction'), dataAutoPlay = thumbsSliders[i].getAttribute('data-autoplay'), dataLoop = thumbsSliders[i].getAttribute('data-loop'), dataEffect = thumbsSliders[i].getAttribute('data-effect'), dataSlidesPerView = thumbsSliders[i].getAttribute('data-slides-per-view'), dataSlidesPerGroup = thumbsSliders[i].getAttribute('data-slides-per-group'), dataSpaceBetween = thumbsSliders[i].getAttribute('data-space-between'), dataCenteredSlides = thumbsSliders[i].getAttribute('data-centered-slides'); //data 属性が設定されていない場合は初期値(デフォルト)を設定及び型を変換 if (!dataSpeed) { dataSpeed = 300; } if (!dataDirection) { dataDirection = 'horizontal'; } //data-autoplay が設定されていれば値を数値に変換し、設定されていなければ大きな値を設定 if (dataAutoPlay) { dataAutoPlay = parseInt(dataAutoPlay); } else { dataAutoPlay = 999999999; } //真偽値の場合は文字列から真偽値に変換 if (dataLoop === 'true') { dataLoop = true; } else { dataLoop = false; } if (!dataEffect) { dataEffect = 'slide'; } if (!dataSlidesPerView) { //デフォルトではサムネイルは4枚表示 dataSlidesPerView = 4; } if (dataCenteredSlides === 'true') { dataCenteredSlides = true; } else { dataCenteredSlides = false; } if (!dataSlidesPerGroup) { dataSlidesPerGroup = 1; } if (!dataSpaceBetween) { dataSpaceBetween = 0; } //サムネイルのスライダーのインスタンスを生成 let mySwiperThumbs = new Swiper(thumbsSliders[i], { direction: dataDirection, speed: parseInt(dataSpeed), autoplay: { delay: dataAutoPlay }, loop: dataLoop, effect: dataEffect, slidesPerView: parseFloat(dataSlidesPerView), centeredSlides: dataCenteredSlides, slidesPerGroup: parseInt(dataSlidesPerGroup), spaceBetween: parseInt(dataSpaceBetween), //各スライドの進行状況を監視 watchSlidesProgress: true, //ビューポートにあるスライドに表示クラスを追加 watchSlidesVisibility: true, //カーソルをデフォルトから grab に変更 grabCursor: true, }); //サムネイルのスライダーを格納する配列に追加 mySwiperThumbsArray.push(mySwiperThumbs); } //メインの各スライダーへの処理 for ( let i=0; i<mainSliders.length; i++ ) { //data 属性の値をパラメータの値として使用する変数に格納 let mainDataSpeed = mainSliders[i].getAttribute('data-speed'), mainDataDirection = mainSliders[i].getAttribute('data-direction'), mainDataAutoPlay = mainSliders[i].getAttribute('data-autoplay'), mainDataLoop = mainSliders[i].getAttribute('data-loop'), mainDataEffect = mainSliders[i].getAttribute('data-effect'), mainDataSlidesPerView = mainSliders[i].getAttribute('data-slides-per-view'), mainDataSlidesPerGroup = mainSliders[i].getAttribute('data-slides-per-group'), mainDataSpaceBetween = mainSliders[i].getAttribute('data-space-between'), mainDataCenteredSlides = mainSliders[i].getAttribute('data-centered-slides'); //data 属性が設定されていない場合は初期値(デフォルト)を設定及び型を変換 if (!mainDataSpeed) { mainDataSpeed = 300; } if (!mainDataDirection) { mainDataDirection = 'horizontal'; } //data-autoplay が設定されていれば値を数値に変換し、設定されていなければ大きな値を設定 if (mainDataAutoPlay) { mainDataAutoPlay = parseInt(mainDataAutoPlay); } else { mainDataAutoPlay = 999999999; } //真偽値の場合は文字列から真偽値に変換 if (mainDataLoop === 'true') { mainDataLoop = true; } else { mainDataLoop = false; } if (!mainDataEffect) { mainDataEffect = 'slide'; } if (!mainDataSlidesPerView) { mainDataSlidesPerView = 1; } if (mainDataCenteredSlides === 'true') { mainDataCenteredSlides = true; } else { mainDataCenteredSlides = false; } if (!mainDataSlidesPerGroup) { mainDataSlidesPerGroup = 1; } if (!mainDataSpaceBetween) { mainDataSpaceBetween = 0; } //メインのスライダーのインスタンスを生成 let mySwiperMain = new Swiper(mainSliders[i], { direction: mainDataDirection, speed: parseInt(mainDataSpeed), autoplay: { delay: mainDataAutoPlay }, loop: mainDataLoop, effect: mainDataEffect, slidesPerView: parseFloat(mainDataSlidesPerView), centeredSlides: mainDataCenteredSlides, slidesPerGroup: parseInt(mainDataSlidesPerGroup), spaceBetween: parseInt(mainDataSpaceBetween), navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, thumbs: { //配列に格納されているサムネイルのスライダーを指定 swiper: mySwiperThumbsArray[i] }, }); } }
以下はスライダーの HTML の例です。
<!-- メインのスライダー(data-* 属性を指定)--> <div class="swiper-container main-slider" data-loop="true" data-slides-per-view="1.3" data-centered-slides="true"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- end of .swiper-container.main-slider --> <!-- サムネイルのスライダー(data-* 属性を指定)--> <div class="swiper-container thumbs-slider" data-slides-per-view="5" data-space-between="5"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="images/swiper_img_01.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="images/swiper_img_02.jpg" alt="" /> </div> ・・・中略・・・ <div class="swiper-slide"> <img src="images/swiper_img_08.jpg" alt="" /> </div> </div> <!-- end of .swiper-wrapper --> </div> <!-- end of .swiper-container.thumbs-slider -->
パララックスプラグイン(Rellax.js)と使う
パララックスを実装できるプラグインの Rellax.js と一緒に Swiper を使う場合、Lazy Loading(遅延読み込み)を有効にしなければ特に問題はありません。
但し、Lazy Loading を有効にすると、ブラウザのサイズ(幅や高さ)を変更するとスライダーの画像が表示されなくなってしまう現象が発生してしまいました。
サンプル(サイズ変更で表示されなくなる)を別ウィンドウで開く
Lazy Loading の問題の解決策(更新)
本来なら、以下のように読み込まれたスライドには swiper-lazy-loaded クラスが付与され、data-background 属性が削除されて代わりに style 属性に background-image が設定されます(2行目)。
<div class="swiper-slide" data-swiper-slide-index="0" role="group" aria-label="2 / 10" style="width: 960px;"> <div class="swiper-lazy bg-slide-image rellax swiper-lazy-loaded" style="transform: translate3d(0px, 14px, 0px); background-image: url("images/swiper_img_01.jpg");"> <div class="slide-content"> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption rellax" data-rellax-speed="7" style="transform: translate3d(0px, -24px, 0px);">caption 01</div> </div> </div> </div>
ブラウザのサイズを変更して画像が表示されないソースを確認すると、以下のように swiper-lazy-loaded クラスは付与されたままですが、style 属性には background-image がなくなってしまっています。
<div class="swiper-slide swiper-slide-prev" data-swiper-slide-index="0" role="group" aria-label="2 / 10" style="width: 960px;"> <div class="swiper-lazy bg-slide-image rellax swiper-lazy-loaded" style="transform: translate3d(0px, 14px, 0px);"> <div class="slide-content"> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption rellax" data-rellax-speed="7" style="transform: translate3d(0px, -24px, 0px);">caption 01</div> </div> </div> </div>
【更新】以前掲載していた方法はリサイズ時にスライドが非表示になるなどあまり良い解決策ではなかったので、以下の部分を書き換えました。(2021年9月22日)
※ 但し、以下の方法でも背景に重複した画像が表示されるなどの問題があり、Rellax.js と併用する場合は Lazy Loading のオプションは使わないほうが無難かと思います。 追記:修正しました。但し、スマホなどでは portrait から landscape に変更した場合など、問題はあります。
この例では背景画像を指定する要素にスタイルを設定するための独自の bg-slide-image というクラスを指定し、遅延読み込み用のクラス swiper-lazy を指定しています。クラス rellax はパララックスプラグイン Rellax.js を適用するためのクラスです。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <!-- 背景画像を指定する要素 swiper-lazy と bg-slide-image を指定--> <div class="swiper-lazy bg-slide-image rellax" data-background="images/swiper_img_01.jpg"> <div class="swiper-lazy-preloader"></div> <div class="slide-content"> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption rellax" data-rellax-speed="7">caption 01</div> </div> </div> </div> <div class="swiper-slide"> <!-- 背景画像を指定する要素 swiper-lazy と bg-slide-image を指定--> <div class="swiper-lazy bg-slide-image rellax" data-background="images/swiper_img_02.jpg"> <div class="swiper-lazy-preloader"></div> <div class="slide-content"> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption rellax" data-rellax-speed="7">caption 02</div> </div> </div> </div> ・・・中略・・・ <div class="swiper-slide"> <!-- 背景画像を指定する要素 swiper-lazy と bg-slide-image を指定--> <div class="swiper-lazy bg-slide-image rellax" data-background="images/swiper_img_08.jpg"> <div class="swiper-lazy-preloader"></div> <div class="slide-content"> <p>Lorem ipsum dolor sit amet, consectetur</p> <div class="caption rellax" data-rellax-speed="7">caption 08</div> </div> </div> </div> </div> <!-- end of .swiper-wrapper --> <div class="swiper-pagination swiper-pagination-white"></div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div> <!-- end of .swiper-container -->
以下の JavaScript では予め背景画像を指定した要素(bg-slide-image クラスを指定した要素)とその要素に設定されている背景画像の URL を取得しています。
resize イベントを使って、リサイズが発生した際に、一度だけ現在のスライドの背景画像を再設定し、setTimeout() を使ってリサイズが完了した時点で .swiper-lazy-loaded が付与された要素に背景画像(background-image)を再度設定しています。(イベント終了時に処理を実行)
現在の(アクティブな)スライドの背景画像を再設定する部分(45〜47行目)は、リサイズ時に画像が非表示になるのを防ぐためで、background-image を含めた背景画像のスタイルを再度適用しています。
また、スクロールした際に背景に重複された画像が表示されないように swiper-lazy-loaded クラスを追加しています(49行目)※ 追記。
設定している背景画像のスタイル(background-size や background-position など)に合わせてそれぞれの値を必要に応じて指定する必要があります。
/* 背景画像のスタイル(CSS 一部抜粋)*/ .bg-slide-image { width: 100%; height: 60vh; background-size: cover; background-position: center center; background-repeat: no-repeat; /*background-image は data-background 属性で指定 */ }
リサイズ操作が終了した時点での処理では、ループが有効になっている場合は、前後に追加のスライドが Swiper によって追加されるので、ループが有効かどうかで分岐して処理しています。
ループが有効な場合は、.swiper-slide の要素(背景画像を設定している要素の親要素)に data-swiper-slide-index という属性が付与されるのでその値を利用しています。但し、インデックスの値に1加算して調整しています。
bg-slide-image クラスは独自のクラスなので必要に応じて遅延用見込みをする背景画像を設定してある要素に付与しているクラスに書き換えるか、22行目の bg-slide-image を23行目のコメントアウトのように swiper-lazy(遅延用見込みをするための Swiper のクラス)に変更します。
<script> //Swiper の初期化 let mySwiper = new Swiper ('.swiper-container', { loop: true, //遅延読み込みするため、先読み込みを無効に preloadImages: false, lazy: { //前後のスライドを先読み込みする loadPrevNext: true, }, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); //.bg-slide-image を指定した(背景画像を設定した)要素の集まり const slide_img_elems = document.getElementsByClassName('bg-slide-image'); //または slide_img_elems = document.getElementsByClassName('swiper-lazy'); //data-background 属性に指定した URL を格納する配列の初期化 const slide_img_bg_src = []; //.bg-slide-image を指定した要素の集まりをループ for (let elem of slide_img_elems) { //data-background 属性に指定した URL を格納 slide_img_bg_src.push(elem.getAttribute('data-background')); } //現在のスライドを表示している要素の背景画像を設定するかどうかを判定する変数 let setupActiveSlide = true; //setTimeout() の戻り値(timeoutID)を入れる変数に初期値 false を設定 let timer = false; //resize イベントにリスナーを登録 window.addEventListener('resize', ()=> { //変数 setupActiveSlide が true であれば(リサイズ時に一度だけ実行) if(setupActiveSlide) { //アクティブなスライドの要素を取得 //.swiper-slide-active が追加付与された.swiper-slide の div 要素 const activeSlide = document.querySelector('.swiper-slide-active'); //背景画像(background-image、background-size、background-position)を設定 activeSlide.style.setProperty('background-image', 'url("' + slide_img_bg_src[mySwiper.activeIndex] + '")'); activeSlide.style.setProperty('background-size', 'cover'); activeSlide.style.setProperty('background-position', 'center center'); //★★★以下を追加★★★ activeSlide.classList.add('swiper-lazy-loaded'); //変数setupActiveSlideをfalseに(リサイズ中は1度だけ上記を実行。リサイズ終了時 true に) setupActiveSlide = false; } if (timer !== false) { clearTimeout(timer); } //リサイズ操作が終了した時点で以下の処理を実行 timer = setTimeout( () => { //.swiper-lazy-loaded が付与された要素(遅延読み込みされた要素)を取得 const img_loaded = document.getElementsByClassName('swiper-lazy-loaded'); for (let i=0; i < img_loaded.length; i++) { if(mySwiper.params.loop) { //ループが有効な場合 //親要素の data-swiper-slide-index 属性の値(スライドのインデックス)に1を加算 let slide_index = parseInt(img_loaded[i].parentElement.getAttribute('data-swiper-slide-index')) + 1; // background-image を上記インデックスを使って設定 img_loaded[i].style.setProperty('background-image', 'url("' + slide_img_bg_src[slide_index] + '")'); }else{ //ループが無効な場合 img_loaded[i].style.setProperty('background-image', 'url("' + slide_img_bg_src[i] + '")'); } //変数 setupActiveSlide を true に setupActiveSlide= true; } }, 200); }); </script>
サンプル(CSS と JavaScript も掲載)を別ウィンドウで開く
Swiper の resize イベント
上記の例では window の resize イベントを使っていますが、Swiper が用意している resize イベントを使うこともできます(window の resize イベントと同じ)。
// Swiper の resize イベント mySwiper.on('resize', function () { ・・・省略・・・ });
Swiper の beforeResize イベント
Swiper のサイズ変更(リサイズ)処理が実施される前に発生する beforeResize イベントを使うこともできます。
// Swiper の beforeResize イベント mySwiper.on('beforeResize', function () { ・・・省略・・・ });