概要
Bootstrap4 modal内で画像を複数表示する際にカルーセルを採用しました。
ライブラリは過去に利用実績のあった、Slick.jsを使えば簡単に作成できる!と思い、取り組んだのですが、
色々躓いた箇所があったので、備忘録として記事を書いてみよう!となりました。(初めての記事です)
環境
bootstrap:4.0.0
slick.js:1.8.0
経緯
最初はなんの対処もせずにmodal上でカルーセルを表示させようとしていました。
しかし、それだとSlickの発火タイミングではModalは表示されていないので、
カルーセルを表示させる箇所のwidthを取得できずにSlick動きません状態でした。
modalが表示されてから、Slick起動
参考サイト1
同じような事象にぶつかっていた方がおりましたので、その記事を参考に下記コードで
let slider = $('.product-img').slick({ //.product-imgはカルーセルで表示したい画像の上位クラス
slidesToShow: 1, //スライド一枚だけ表示
lazyLoad: 'progressive', //ページが読み込まれた後に非表示の画像を読み込み
dots: true //カルーセルの下にドット表示
});
$('.js-modal-open').on('click', function(){ //.js-modal-openはモーダル表示する際に押下するクラス
slider.css('opacity', 0);
slider.animate({'z-index':1}, 100, function(){
slider.slick('setPosition');
slider.animate({'opacity':1});
});
});
modal表示するボタンのコード
<li class="js-modal-open" data-toggle="modal" data-target=".modal-lg-product{{ $product->id }}">
<img data-lazy="{{ asset('product/'.$product->product_images->first()->path) }}">
</li>
このliを押下すると該当するmodalが表示される感じ
カルーセルで表示したい画像たち
<div class="product-img">
@foreach ($product->product_images as $image)
<img src="{{ asset('product/'.$image->path) }}">
@endforeach
</div>
上記コードでは、表示はされるが下記問題が発生
・modalが表示されてから、数秒画像が表示されない
・複数画像がある場合は、ドットか矢印を押下し、カルーセルを動かさないと画像が表示されない
解決
let slider = $('.product-img').slick({
slidesToShow: 1,
lazyLoad: 'progressive',
dots: true
});
$('.js-modal-open').on('click', function () {
setTimeout(function () { //.js-modal-openを押下時165ミリ秒後にSlickが動作
slider.css('opacity', 0); //なくてもOK、表示をスムーズにするために入れてる
slider.slick('setPosition'); //slickのwidthを再計算
slider.animate({ 'opacity': 1 }); //なくてもOK、表示をスムーズにするために入れてる
}, 165);
});
165ミリ秒は色々試した結果、いい感じに表示されたのがこの値だったので設定した感じです。
環境ごとにこの値は変更する必要があると思いますが、僕の環境ではこの値がベストでした。