Published
- 3 min read
Swiperで作成したスライダーを3つ連携させる

結論
タイトルの内容は、上司の助言・下記の記事を参考に意図した動きになった。
3つの swiper を完全に同期・連動させる方法 (※controller で上手く動かない人向け)【Swiper 10系】
やりたかったことは、「slideChangeTransitionEnd イベントと thumbs プロパティを併用する」の内容だった。
参考に試したサンプルコード
CDN(ver11)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.js"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.css"
/>
HTML
<div class="container">
<div class="swiper js-sample-slider3">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://placehold.jp/363636/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/545454/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/676767/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/7b7b7b/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/888888/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/999999/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/adadad/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/c8c8c8/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/dddddd/ffffff/500x300.png" />
</div>
<!-- <div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div> -->
</div>
</div>
<div class="slider-wrap">
<div class="swiper js-sample-slider1">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://placehold.jp/363636/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/545454/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/676767/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/7b7b7b/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/888888/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/999999/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/adadad/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/c8c8c8/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/dddddd/ffffff/500x300.png" />
</div>
</div>
</div>
</div>
<div class="slider-wrap">
<div class="swiper js-sample-slider2">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://placehold.jp/363636/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/545454/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/676767/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/7b7b7b/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/888888/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/999999/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/adadad/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/c8c8c8/ffffff/500x300.png" />
</div>
<div class="swiper-slide">
<img src="https://placehold.jp/dddddd/ffffff/500x300.png" />
</div>
</div>
</div>
</div>
</div>
JS
// 中央
const swiper1 = new Swiper('.js-sample-slider1', {
direction: 'vertical',
slidesPerView: 1,
freeMode: {
enabled: true,
momentumRatio: 0.6,
momentumVelocityRatio: 0.8
}
})
// 右
const swiper2 = new Swiper('.js-sample-slider2', {
direction: 'vertical',
slidesPerView: 1,
freeMode: {
enabled: true,
momentumRatio: 0.6,
momentumVelocityRatio: 0.8
}
})
// 左
const swiper3 = new Swiper('.js-sample-slider3', {
direction: 'vertical',
slidesPerView: 1,
watchSlidesProgress: true,
freeMode: true,
thumbs: {
swiper: swiper2
}
})
let slideNum
swiper1.on('slideChangeTransitionEnd', (slider) => {
slideNum = slider.realIndex
swiper3.slideToLoop(slideNum, undefined, false)
swiper2.slideToLoop(slideNum, undefined, false)
})
swiper2.on('slideChangeTransitionEnd', (slider) => {
slideNum = slider.realIndex
swiper3.slideToLoop(slideNum, undefined, false)
swiper1.slideToLoop(slideNum, undefined, false)
})
swiper3.on('slideChangeTransitionEnd', (slider) => {
slideNum = slider.realIndex
swiper1.slideToLoop(slideNum, undefined, false)
swiper2.slideToLoop(slideNum, undefined, false)
})
CSS
.container {
display: flex;
gap: 20px;
}
.js-sample-slider1,
.js-sample-slider2,
.js-sample-slider3 {
width: 100%;
height: 400px;
}
.js-sample-slider1 img,
.js-sample-slider2 img,
.js-sample-slider3 img {
width: 100%;
height: 100%;
object-fit: cover;
}
.slider-wrap {
height: 400px;
overflow: hidden;
}
.js-sample-slider1,
.js-sample-slider2 {
overflow: visible;
}
.js-sample-slider1,
.js-sample-slider2,
.js-sample-slider1 .swiper-slide,
.js-sample-slider2 .swiper-slide {
height: 100px !important;
}
.swiper-slide-active {
filter: brightness(0.8);
}