Makery Blog

西麻布のクリエイティブラボ「Makery」でテクノロジーとアイデアをこねています。

slick.jsを使ってスライドショーを作る(スライドごとに秒数指定)

各スライドごとに秒数指定できるようなスライドショーを作りましょう。
自前でjsを使ってスライドショーを実装するのは結構大変だと思うので、今回は自分がよく使わせてもらっているslick.jsを使って手軽にできるようにしてみます。

DEMO

なおslick.jsを使う諸々の準備等は公式のgithubページなどを参考にしてください。



まず下記のようなスライド用HTML要素を用意します。

        <ul class="slick-items">
            <li class="slick-item">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide1</p>
                </div>
            </li>

            <li class="slick-item">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide2</p>
                </div>
            </li>

            <li class="slick-item">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide3</p>
                </div>
            </li>
        </ul>

jsは下記のような感じで。

$(function () {
    var $slickItems = $(".slick-items");
    $slickItems.slick({
        arrows:false, //矢印は消す
        autoplay: true,
        autoplaySpeed: false  //autoplaySpeedは各スライドに設定するので切っておく
    }).on("afterChange", function(event, slick, currentSlide) {
            if(currentSlide === 0){
                $(this).slick("slickSetOption", "autoplaySpeed", 1000); //1枚目
            }else if(currentSlide === 1){
                $(this).slick("slickSetOption", "autoplaySpeed", 2000); //2枚目
            }else{
                $(this).slick("slickSetOption", "autoplaySpeed", 3000); //3枚目
            }
        });
});

とりあえずは、これで各スライド3枚分の秒数指定することができました。slickで使えるafterChangeイベントを使ってスライド処理が発火した後に、各スライドの秒数を指定しています。
ただこれだとスライドのlist要素が増えた時にいちいちif文が増えてしまいますね。

なので各スライド用のlist要素が増えた場合でも、jsの編集が必要ないようにしましょう。
listの各要素にdata属性を付け加えていきましょう。

        <ul class="slick-items">    <!--↓追加--> 
            <li class="slick-item" data-slidetime="1000">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide1</p>
                </div>
            </li>
                    <!--↓追加-->
            <li class="slick-item" data-slidetime="2000">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide2</p>
                </div>
            </li>
                    <!--↓追加-->
            <li class="slick-item" data-slidetime="3000">
                <div class="slick-itemBox">
                    <p class="slick-item--txt">slick-slide3</p>
                </div>
            </li>
        </ul>

各list要素のdata-slidetimeで設定した秒数を取得する関数を作ります。

function getSlideData($selector,index) {
        var slideDataAray = [];
        $selector.each(function () {
            var selfSlideData = $(this).data('slidetime');
            slideDataAray.push(selfSlideData);
        });
        return slideDataAray[index];
    }

先ほどのjsを下記のように修正します。

    var $slideItem = $(".slick-item");
    var $slickItems = $(".slick-items");
    $slickItems.slick({
        arrows:false,
        autoplay: true,
        autoplaySpeed: false
    }).on("afterChange", function(event, slick, currentSlide) {
    //現在のスライド数を取得
        var currentSlideNum = slick.currentSlide;
    //getSlideData関数を使って、現在のスライドのインターバルを取得
        var slideInterval = getSlideData($slideItem,currentSlideNum);
            if(currentSlide === currentSlideNum){ 
     //各スライドに設定された秒数を指定
                $(this).slick("slickSetOption", "autoplaySpeed", slideInterval);
            }
        });

これでlist要素がいくら増えても、いちいちif文を増やす必要はないですね!
これでできた!と思ったらこのままだとinit時のタイミングでのslickオプションの指定が効かないので、初回ループの1枚目スライドに秒数指定が効かないですね・・。

なのでinit時にautoplayオプションの時間指定を効かせて発火させるようにします。

    var $slideItem = $(".slick-item");
    var $slickItems = $(".slick-items");

//init時の処理追加
    $slickItems.on('init', function (e, slick) {        
        var slideInterval = getSlideData($slideItem,0);
        var currentSlideNum = slick.currentSlide;
        if (currentSlideNum === 0) {
                setTimeout(function () {
                    $(this).slick("slickSetOption", "autoplay", true, true);
                }, slideInterval);
        }
    });

    $slickItems.slick({
        arrows:false,
        //autoplay: true, init時にoption指定したので、こちらのautoplayはいらない
        autoplaySpeed: false //autoplaySpeedは各スライドに設定するので切っておく
    }).on("afterChange", function(event, slick, currentSlide) {
        var currentSlideNum = slick.currentSlide;
        var slideInterval = getSlideData($slideItem,currentSlideNum);
            if(currentSlide === currentSlideNum){
                $(this).slick("slickSetOption", "autoplaySpeed", slideInterval);
            }
        });

これでスライド毎に秒数の違うスライドショーができたかと思います!
DEMOのソースコードgithubで公開しています。
github.com

今この記事を読んでいるあなたの参考になれば幸いです。

参考URL
[Slick.js] 実行完了後にautoplayなどのオプションを有効にする方法 – 零弐壱蜂
Slick.jsでスライドごとに表示する秒数(autoplaySpeed)を変更する方法 | 6666666