この記事は、動的に追加したDOM要素にSlickのスライダーを適用した時に発生する問題点とその解決策をまとめたものです。この記事を読むことで、例えば、jQueryなどでDOM要素を動的に追加した後に、Slickでスライダーを適用し、スライダーが表示されない理由がわかり、その状況の解決方法も理解できると思います。
Slickについては以下の記事も参照ください。
動的に追加したDOM要素にSlickを適用すると起きる現象
Slickは、Slickが初期化されたタイミングでSlickから見えているDOMをスライダーとして扱うので、DOMを動的に追加するより前にSlickが初期化されるとSlickからはスライダーにする要素が見えない状態になります。
Slickは正直にそのまま中身のないスライダーを生成します。
動的にDOM追加する前のHTML構成
Slickを適用する親要素だけ用意して、子要素はjQueryなどで追加する想定です。
<div class="slider">
<!--動的に追加-->
<!--動的に追加-->
<!--動的に追加-->
</div>
動的にDOM追加した後のHTML構成
jQueryなどで子要素を追加した後の構成です。
<div class="slider">
<div class="slide"></div><!--動的に追加-->
<div class="slide"></div><!--動的に追加-->
<div class="slide"></div><!--動的に追加-->
</div>
Slickを追加した後のHTML構成
Slickを適用した後の構成です。本来は、動的に追加した子要素を括るようにSlickがdivを追加するのが期待した動きです。しかし、動的に追加した子要素を無視したかのような位置にSlickのスライダーが挿入されて、スライダーの中身が空っぽになります。
<div class="slider">
<div>ここにスライダー追加されるが中身がない</div>
<div class="slide"></div><!--動的に追加-->
<div class="slide"></div><!--動的に追加-->
<div class="slide"></div><!--動的に追加-->
</div>
動的に追加したDOM要素にSlickを適用する方法
jQueryで動的に追加した要素にSlickを適用する場合
動的に要素を追加したタイミングで再度Slickを初期化する。
最初から、動的に要素を追加した後で初期化すればよいのですが、それができない場合は、次のように再度初期化すればDOMを見つけてくれます。
DOM要素の追加処理
$('.slider').slick('unslick');
$('.slider').slick();
初期化する時にオプションをたくさん指定している場合は、functionとして定義してしまう方が簡単です。
DOM要素の追加処理
$('.slider').slick('unslick');
sliderInit();
function sliderInit(){
$('.slider'').slick({
dots: false,
infinite: true,
cssEase: 'ease',
speed: 800,
autoplay: true,
autoplaySpeed: 4000,
adaptiveHeight: true,
centerMode: false,
fade: false,
pauseOnHover:true,
});
};
Ajaxで動的に追加した要素にSlickを適用する場合
BASEやカラーミーショップなどのレンタルショッピングカートサイトでは用意されているテンプレートタグで必要な情報が得られるようになっているとは限りません。
仕方なく、Ajaxで他のページから動的にデータを取ってくるしかない状況があります。
Ajaxでデータを取得した後に、DOM要素を追加してSlickのスライダーにする場合はjQueryの時とは記述する場所が変わります。
Ajaxの場合は、successの中に先ほどのslickの初期化処理を書きます。AjaxでDOMを構築するのがsuccessの中なので、そのあとに書きます。
$.ajax({
url: 'https://なんらかのURL',
cache: false,
dataType:'html',
success: function(html){
DOM要素の追加処理
$('.slider').slick('unslick');
sliderInit();
}
});
まとめ
Slickは簡単にスライダーを実現できるのですが、javascriptで要素を追加する時には実行順序をよく考えないと上手くいかないというお話でした。