非表示・表示切り替えにも対応していく。
どういうことか
普通はhtmlなりphpなりでスライダー部を作って、それにslick.jsを付与する。
今回はjsでスライダー部を作って、slick.jsを付与する。
.append()なり何なりで出力したhtmlには.slick()が反映されない。
これはslickに限らない話で、出力と付与のタイミングが合わないとそうなる。
できないんじゃなくて、できる作り方があるよという話。
jsの仕様を理解した組み方が求められる。
やっていく
最終的にこんな感じにするとする。
<script>
$(function(){
$('ul.slider').slick({
dots: true,
infinite: true,
speed: 500,
});
})
</script>
<div class="wrap">
<ul class="slider" data-name="slider01">
<li>***</li>
<li>***</li>
<li>***</li>
⋮
</ul>
<ul class="slider" data-name="slider02">
<li>***</li>
<li>***</li>
<li>***</li>
⋮
</ul>
<ul class="slider" data-name="slider03">
<li>***</li>
<li>***</li>
<li>***</li>
⋮
</ul>
</div>
スライダーを複数設定して、1個だけ表示する。
ボタンとかで表示するスライダーを切り替える。
display:none;なスライダーは表示時にぶっ壊れる(jsが反応しない)ことは珍しくなく、slick.jsも同様。
それも対応する。
htmlはこんな感じにしておくとする。
<div class="wrap">
</div>
.wrapの中にjsでスライダーを突っ込む。
スライダーの生成・出力
直近で作った要素も混ぜつつ。
配列にまとめた内容を展開して作っていく。
$(function(){
const slider01Ary = {sliderName:'slider01',slideName:['slider01_01','slider01_02','slider01_03','slider01_04','slider01_05',...]};
const slider02Ary = {sliderName:'slider02',slideName:['slider02_01','slider02_02','slider02_03','slider02_04','slider02_05',...]};
const slider03Ary = {sliderName:'slider03',slideName:['slider03_01','slider03_02','slider03_03','slider03_04','slider03_05',...]};
const slider04Ary = {sliderName:'slider04',slideName:['slider04_01','slider04_02','slider04_03','slider04_04','slider04_05',...]};
⋮
let sliderSet = '';
const slider01Num = slider01Ary['slideName'].length;
for(i=0;i<slider01Num;i++){
if(i == 0){ sliderSet += '<ul class="slider" data-name="'+slider01Ary['sliderName']+'">'; }
sliderSet += '<li>'+slider01Ary['slideName'][i]+'</li>';
if(i == slider01Num - 1){ sliderSet += '</ul>'; }
}
const slider02Num = slider02Ary['slideName'].length;
for(i=0;i<slider02Num;i++){
if(i == 0){ sliderSet += '<ul class="slider" data-name="'+slider02Ary['sliderName']+'">'; }
sliderSet += '<li>'+slider02Ary['slideName'][i]+'</li>';
if(i == slider02Num - 1){ sliderSet += '</ul>'; }
}
⋮
$('.wrap').append(sliderSet);
$('.wrap .slider').slick({
dots: true,
infinite: true,
speed: 500,
});
})
.slick()は生成のあとに書く。
手前に書くと詰む。
手前に書いた.slick()が出力したDOM要素に被ってなきゃいいんだけどね。
例えばスライドを1個だけhtml側で設置してあってjsで追加するみたいなことをした場合。
元々ある用に.slick()を書いて、上記のようなjsでスライドを出力してまた.slick()を書いてもダメ。
先に書いたほうが優先されて詰み。
.slick(‘setPosition’)を入れても意味がない。
setPositionを使うときは、表示が壊れててもとにかく.slick()があらかじめ適用されてることが前提になる。
はじめからこの形で組んでたらいいんだけど、追っかけでスライド追加をやっていくときに混乱すると思います。混乱しました。
表示の切り替えボタンを付ける
こんな感じで
<style>
ul.slider{ display:none;}
ul.slider:first-child{ display:block;}
</style>
<div class="wrap">
<ul class="slider" data-name="slider01">
</ul>
<ul class="slider" data-name="slider02">
</ul>
<ul class="slider" data-name="slider03">
</ul>
⋮
</div>
<div class="change">
<button type="button" data-name="slider01">slider01</button>
<button type="button" data-name="slider02">slider02</button>
<button type="button" data-name="slider03">slider03</button>
⋮
</div>
切り替え部分のHTMLはこうだとして
<div class="change">
</div>
こう
$(function(){
const slider01Ary = {sliderName:'slider01',slideName:['slider01_01','slider01_02','slider01_03','slider01_04','slider01_05',...]};
const slider02Ary = {sliderName:'slider02',slideName:['slider02_01','slider02_02','slider02_03','slider02_04','slider02_05',...]};
⋮
let changeSet = '';
changeSet += '<button type="button" data-name="'+slider01Ary['sliderName']+'">'+slider01Ary['sliderName']+'</button>';
changeSet += '<button type="button" data-name="'+slider02Ary['sliderName']+'">'+slider02Ary['sliderName']+'</button>';
⋮
$('.change').append(changeSet);
$(document).on('click','.change button',function(){
$('.wrap ul.slider').hide();
$('.wrap ul.slider[data-name="'+$(this).attr('data-name')+'"]').fadeIn(function(){
$(this).slick('setPosition');
});
})
})
出力したbuttonとかを発火させる場合は$(document)から書き出したほうが楽。
setPositionを付けてるけど、なんかこれ、付けなくても良さげな動作をしたときもある。
なんだろうね、まあ書いたほうが無難ですかね。
コメント