スライドの枚数によって、スライダーが発火したりしなかったりするようになっています。
CMSの記事を出力する箇所で使用しており、「記事の数が一定以上になった時のみスライダーを実行するようにしたい」とのご要望も着手前からあり実装したものです。
本案件自体にはチームで実装していたところに途中から参加したのですが、すでにSwiperを使用していたためSwiperで実装しております。が、Splideならばもっと簡単にできるようなので、こちらも試してみたいです。
<div class="c-tabs js-tab-scope">
<div class="c-tabs__tab-list">
<button type="button" data-trigger-id="tab1" class="c-tabs__tab js-tab-trigger is-current">スライド2枚</button>
<button type="button" data-trigger-id="tab2" class="c-tabs__tab js-tab-trigger">スライド3枚(SPのみ)</button>
<button type="button" data-trigger-id="tab3" class="c-tabs__tab js-tab-trigger">スライド4枚(両方)</button>
</div>
<div class="c-tabs__body">
<div data-target-id="tab1" class="c-tabs__tab-panel js-tab-target is-current">
<div class="c-slider-2">
<div class="swiper c-slider-2__slide js-slider-2">
<div class="swiper-wrapper c-slider-2__container">
<div class="c-slider-2__item swiper-slide">Slide 1</div>
<div class="c-slider-2__item swiper-slide">Slide 2</div>
</div>
<!-- navigation buttons -->
<div class="c-slider-2__btn-wrap">
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</div>
<!-- [/c-slider-2] -->
</div>
<div data-target-id="tab2" class="c-tabs__tab-panel js-tab-target">
<div class="c-slider-2">
<div class="swiper c-slider-2__slide js-slider-2">
<div class="swiper-wrapper c-slider-2__container">
<div class="c-slider-2__item swiper-slide">Slide 1</div>
<div class="c-slider-2__item swiper-slide">Slide 2</div>
<div class="c-slider-2__item swiper-slide">Slide 3</div>
</div>
<!-- navigation buttons -->
<div class="c-slider-2__btn-wrap">
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</div>
<!-- [/c-slider-2] -->
</div>
<div data-target-id="tab3" class="c-tabs__tab-panel js-tab-target">
<div class="c-slider-2">
<div class="swiper c-slider-2__slide js-slider-2">
<div class="swiper-wrapper c-slider-2__container">
<div class="c-slider-2__item swiper-slide">Slide 1</div>
<div class="c-slider-2__item swiper-slide">Slide 2</div>
<div class="c-slider-2__item swiper-slide">Slide 3</div>
<div class="c-slider-2__item swiper-slide">Slide 4</div>
</div>
<!-- navigation buttons -->
<div class="c-slider-2__btn-wrap">
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</div>
<!-- [/c-slider-2] -->
</div>
</div>
</div>
<!-- [/c-tabs] -->
.c-tabs__tab-list {
margin-bottom: 10px;
display: flex;
gap: 10px;
}
.c-tabs__tab {
display: inline-block;
padding: 0.5em;
color: inherit;
touch-action: manipulation;
cursor: pointer;
}
.c-tabs__tab.is-current {
background-color: black;
color: #fff;
}
.c-tabs__tab-panel {
display: none;
}
.c-tabs__tab-panel.is-current {
display: block;
}
.c-slider-2__item {
aspect-ratio: 16/9;
display: grid;
place-content: center;
background-color: lightgrey;
}
.c-slider-2 .swiper:not(.swiper-initialized) .c-slider-2__container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 30px;
}
@media screen and (max-width: 750px) {
.c-slider-2 .swiper:not(.swiper-initialized) .c-slider-2__container {
grid-template-columns: repeat(2, 1fr);
gap: 15px;
}
}
.c-slider-2 .swiper:not(.swiper-initialized) .swiper-button-prev,
.c-slider-2 .swiper:not(.swiper-initialized) .swiper-button-next {
display: none;
}
document.addEventListener('DOMContentLoaded', () => {
'use strict';
let swiperInstances = [];
const sliders = document.querySelectorAll('.js-slider-2'),
mql = window.matchMedia('(max-width: 767px)');
checkMediaQuery(mql); //初回実行
mql.addEventListener('change', checkMediaQuery);
function checkMediaQuery(mq) {
// 既存のswiperインスタンスを破棄
swiperInstances.forEach((swiper) => swiper.destroy(true, true));
swiperInstances = [];
sliders.forEach((slider) => {
const slideCount = slider.querySelectorAll('.swiper-slide').length;
if (mq.matches && slideCount >= 3) {
// SP時 3枚以上
handleSwiper(
slider,
2,
15,
'.swiper-button-next',
'.swiper-button-prev'
);
} else if (!mq.matches && slideCount >= 4) {
// PC時 4枚以上
handleSwiper(
slider,
3,
30,
'.swiper-button-next',
'.swiper-button-prev'
);
}
});
}
function handleSwiper(
slider,
slidesPerView,
spaceBetween,
nextElSelector,
prevElSelector,
breakpoints = null
) {
const swiper = new Swiper(slider, {
loop: true,
speed: 300,
slidesPerView: slidesPerView,
spaceBetween: spaceBetween,
navigation: {
nextEl: slider.querySelector(nextElSelector),
prevEl: slider.querySelector(prevElSelector)
},
breakpoints: breakpoints
});
swiperInstances.push(swiper);
}
});
document.addEventListener('DOMContentLoaded', () => {
'use strict';
const triggerSelector = '.js-tab-trigger';
const targetSelector = '.js-tab-target';
const scopeSelector = '.js-tab-scope';
const currentClass = 'is-current';
const triggers = document.querySelectorAll(triggerSelector);
if (!triggers) return;
for (const trigger of triggers) {
trigger.addEventListener('click', () => {
const targetId = trigger.dataset.triggerId;
const thisScope = trigger.closest(scopeSelector);
const thisTriggers = thisScope.querySelectorAll(triggerSelector);
const thisTargets = thisScope.querySelectorAll(targetSelector);
const currentTarget = thisScope.querySelector(
`[data-target-id="${targetId}"]`
);
for (const thisTrigger of thisTriggers) {
thisTrigger.classList.remove(currentClass);
}
for (const thisTarget of thisTargets) {
thisTarget.classList.remove(currentClass);
}
trigger.classList.add(currentClass);
currentTarget.classList.add(currentClass);
});
}
});