昨日Twitterのタイムラインで下記を見かけました
slickのがたつきの件、NxWorldさんのサイトのサンプルでもなってるからやっぱり自分だけじゃないな。/https://t.co/EJ5swAVGAu
— ヤマシタレイコ|OOOPEN (@OOOPEN_jp) January 30, 2019
以前このプラグインを使った時に同じような不具合に直面し、自力で何とかした経験があるので、同じように困っている方の参考になれば。。
#現象
ここのスライドのNextとかPrevを押すと分かりますが、2周目の最初のスライドに来た時と、最初のスライドから最後のスライドに戻る時にがたつきます。
これは.slick-current
というクラスが来た時に透過にしたり大きくしたりしているのですが、がたつくパターンの場合クラスが付与されるまでにDOMの操作が発生しその処理時間の差でがたつくのだと思います。
#対処方法
###HTML
HTMLは特に普通と一緒です。
<div class="slider" id="js-slider">
<div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-4.jpg" width="800" height="480" alt=""></div>
<div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-6.jpg" width="800" height="480" alt=""></div>
<div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-7.jpg" width="800" height="480" alt=""></div>
</div>
###JavaScript
js側で小細工をします。
不具合があっても同じように透過させたりしたいのであれば、
- 最初のスライドから最後のスライドに移動する際に最後のスライドに対して
.slick-current
クラスが付与される時と同じ処理をするクラスを付与する - 最後のスライドから最初のスライドに移動する際に最初のスライドに対して
.slick-current
クラスが付与される時と同じ処理をするクラスを付与する
という感じにすればいけそうな気がします。
移動する際の処理は、slickのイベントであるbeforeChange
で出来ます。
const $slider = $("#js-slider");
// 左右の透過の2周目ががたつく対応
$slider.on("beforeChange", (event, slick, currentSlide, nextSlide) => {
$slider.find(".slick-slide").each((index, el) => {
const $this = $(el),
slickindex = $this.attr("data-slick-index");
if (nextSlide == slick.slideCount - 1 && currentSlide == 0) {
// 現在のスライドが最初のスライドでそこから最後のスライドに戻る場合
if (slickindex == "-1") {
// 最後のスライドに対してクラスを付与
$this.addClass("is-active-next");
} else {
// それ以外は削除
$this.removeClass("is-active-next");
}
} else if (nextSlide == 0) {
// 次のスライドが最初のスライドの場合
if (slickindex == slick.slideCount) {
// 最初のスライドに対してクラスを付与
$this.addClass("is-active-next");
} else {
// それ以外は削除
$this.removeClass("is-active-next");
}
} else {
// それ以外は削除
$this.removeClass("is-active-next");
}
});
});
// スライダー
$slider.slick({
centerMode: true,
slidesToShow: 1,
centerPadding: "20%",
speed: 500,
arrows: true,
dots: true
});
###CSS
そして、is-active-next
クラスに対してcss側でslick-current
クラスと同じ処理をします。
.slider__item {
opacity: 0.34;
transition: opacity 0.4s;
}
.slick-slide.slick-current .slider__item,
.slick-slide.is-active-next .slider__item {
opacity: 1;
}
これで多分うまくいく(はず)....
###サンプル
CodePenにサンプルを置いておきましたので実際の動作はこちらをご覧ください!