画面内に現れてからスライダーを自動再生(Slick×ScrollOut.js)Topics

スニペット集

長いランディングページの中間部分に設置したスライダーを、自動再生したいというご要望がありました。

ページを開いた時点ではなく、スライダーが画面に現れたときに自動再生を開始するのが理想です。

スライダーには「slick」を、
スライダーが画面に現れたときを判別するために「ScrollOut」を使用しました。

See the Pen 【スライダー】画面内に入ったら自動再生させる by zungu (@zungu) on CodePen.

スライダーの設定

まず、PCビューでのスライダー設定です。

ドットナビゲーションに独自のデザインを適用させたいので、slickのCSSが影響しないように独自のclass「slide_dots」を付与した要素に表示させています。
同じように「前へ」「次へ」の矢印にも独自の要素を指定。

画面に現れてから自動再生したいので、いったん「autoplay: false」としておきます。

 $(".js-slider").not('.slick-initialized').slick({
    arrows: true,
    adaptiveHeight: false,
    dots: true,
    dotsClass: "slide_dots", //class名変更(デフォルトはslick-dots)
    prevArrow: '<div class="slide_arr prev"></div>',
    nextArrow: '<div class="slide_arr next"></div>',
    autoplaySpeed: 5000,
    speed: 400,
    fade: true,
    infinite: true,
    autoplay: false
  });

そして、スマホビューでのスライダー設定。

「PCでは問題ないのに、スマホで自動再生されない!!!!」😨
という問題に対処するため、PCとスマホビューで設定を一部変えます。

この問題の原因は、スマホでのページスクロールに反応してslickが自動再生をストップしてしまうからです。
slickでは、hover時にautoplayが止まらないようにする設定がtrue(ON)になっているので、スマホではこれらをfalse(OFF)にします。

    $(".js-slider").not('.slick-initialized').slick({
      arrows: true,
      adaptiveHeight: false,
      dots: true,
      dotsClass: "slide_dots", //class名変更(デフォルトはslick-dots)
      prevArrow: '<div class="slide_arr prev"></div>',
      nextArrow: '<div class="slide_arr next"></div>',
      autoplaySpeed: 5000,
      speed: 400,
      fade: true,
      infinite: true,
      autoplay: false,
    });

これをスマホとPC判別の中に書きます。

var strWindowWidthTop = window.innerWidth ? window.innerWidth : $(window).width();
var spW = '767';
  
if (strWindowWidthTop <= spW) {
    // スマホの設定をここに
    });
} else {
   // PCの設定をここに
}

スクロールイベントの設定

次は、「画面内に現れたら」の設定です。

私が「ScrollOut」を使うときは、基本設定として、
画面内に現れた要素にclass「show」を1度だけ付与するようにしています。
class=”show” の要素に animation を指定して、
「スクロールしたらふわっと表示される」
というような実装をしているのですが、
今回は、スライダー要素に対しての設定を追加します。

画面内に現れた要素がスライダー(.js-slider)だったら、
slickSetOptionで、autoplayをtrueに書き換えます。
ちゃんと切り替わったか、確認しづらいので、
目印として、class=”autoplay”付与も追加設定しました。

ScrollOut({
  cssProps: {
    once: false
  },
  onShown: function (el) {
    // 要素が画面内にある場合
    el.classList.add("show");

    // スライダー自動再生
    if (el.classList.contains('js-slider')) {
      el.classList.add("autoplay");
      $(function () {
        $(".js-slider").slick('slickSetOption', 'autoplay', true, true);
      });
    }
  },
});

これで、ページが読み込まれ表示された時点ではなく、画面にスライダーが現れたときに自動再生されるようになりました!

画面にスライダー要素が現れた時点でslickが発動するような設定でもいいのかもしれませんが、アンカーリンクなどで要素の位置を正確に測りたい場合にちょっと問題が発生します。

今回はスライダー要素以降の部分にアンカーリンクさせる必要があり、このような形にしました。
ページ読込時にSlick適用させているので、要素の位置がずれるのを回避できます。

もっと改良したい!

スライダー要素が画面から消えたら自動再生を止めるっていうのも実装できたらもっといいかも、と思ったのですが、「once: false」設定しているせいかうまくいかず、なぜか、onHidden: function (el) {…}の設定が無視される事態に。。。(。´・ω・)?
今回はあきらめました。。。
次回またチャレンジしてみようと思います!