スライダー画像を実現するのに便利なslick slider。しかし、スライダー画像が一瞬大きくなる現象が起きてハマった。
通常、slickの初期化をこんな風に行う。
$('.slider').slick({
slidesToShow: 3
});
HTMLのタグはこうのように書く。
<div class="slider">
<img src="01.png"/>
<img src="02.png"/>
<img src="03.png"/>
</div>
画像が一瞬大きくなる現象はこのように起きるのだと思う。
- HTMLロード
- JavaScript実行、slickの初期化
- 画像のロード完了
- 一瞬実サイズで画像表示される
- slickがスライダー内におさまる画像サイズに変更する
lazyLoadを使って解決
細かい説明の前に解決法から書いてしまおう。lazyLoadオプションとlazyLoadedイベントを使って解決!自動再生にも対応。
//
// この中はクラスを過程。よってthisを使っている。
//
// ロードすべき画像数
this.num_images = $('.slider').find("img").size();
// ロードされた画像数
this.num_loaded_images = 0;
// 自動再生中ならtrue
this.is_autoplaying = false
$('.slider').slick({
slidesToShow: 3,
lazyLoad: 'progressive'
});
self = this;
// 画像がロードされるたびに呼ばれるイベントlazyLoaded
$('.slider').on("lazyLoaded", function(event, slick, image, imageSource) {
if (self.num_loaded_images < self.num_images) {
// ロードされた画像をカウント
self.num_loaded_images += 1;
}
if (!self.is_autoplaying && (self.num_loaded_images === self.num_images)) {
// まだ自動再生中でなく、すべての画像が読み込まれたら、自動再生を開始する
$('.slider').slick("slickPlay");
self.is_autoplaying = true;
}
});
スライダー内のimgタグはsrcではなくdata-lazyを使う
<div class="slider">
<img data-lazy="01.png"/>
<img data-lazy="02.png"/>
<img data-lazy="03.png"/>
</div>
typoしてるかもしれないので、そのまま動くか不明・・・でも、こんな感じでうまくいくのは確実です。
動きの流れ
- HTMLが読み込まれる
- slick初期化が行われる
- slickで画像のロードを待って、ロードされたらlazyLoadedイベントを呼ぶ
- すべての画像がロードされたら自動再生を開始する
slick初期化でautoplay: trueとオプションを渡してしまうと画像がロードされる前に自動再生されてしまいかっこ悪いです。よって、画像がすべてロードされてから自動再生メソッドをコールしています。
lazyLoadはondemandではなくprogressiveを指定する
ondemandを指定するとスライドして画像が必要になった時にロードする動きになるため、自動再生したい場合はには不向きです。progressiveにすると、スクロールの外の画像も全てロードしてくれます。