Как центрировать новый активный слайд swiper?
Доброго времени суток.
Есть два свайпера, один управляет другим последством thumbs. Thumbs-слайдов больше. По событию "slideChangeTransitionStart" удаляю со всех thumbs классы -active, -prev, -next и вешаю на те , которые мне необходимы. В параметрах прописал centeredSlides: true и controller by container.
Я не могу отцентрировать новый активный слайд. Отслеживание по другим событиям не подходит. Мне нужно обновить параметры слайдера после назначения нового активного thumb'а, кто-нибудь знает как это можно сделать? или может есть другой путь? Буду благодарен за любую помощь.
historySlider.on("slideChangeTransitionStart", function () {
// Get the active-slide when slide is changing
let activeHistoryImage = document.querySelector(".history__slide.swiper-slide-active");
// Get the active-slide data-slide attribute
let activeHistoryImageAttr = activeHistoryImage.getAttribute("data-slide");
let historyTimestamp = document.querySelectorAll(".history__stamp");
// Get the cycle from timeline row
historyTimestamp.forEach(item => {
if (item.dataset.target == activeHistoryImageAttr) {
let activeTimestamp = item;
// Remove from any timeline slide active class
historyTimestamp.forEach(elem => {
elem.classList.remove("swiper-slide-active");
});
// Remove from any timeline slide prev class
historyTimestamp.forEach(elem => {
elem.classList.remove("swiper-slide-prev");
});
// Remove from any timeline slide next class
historyTimestamp.forEach(elem => {
elem.classList.remove("swiper-slide-next");
});
// Add active class to activeTimestamp, previous to previous and next to next
activeTimestamp.classList.add("swiper-slide-active");
activeTimestamp.previousElementSibling.classList.add("swiper-slide-prev");
activeTimestamp.nextElementSibling.classList.add("swiper-slide-next");
}
});
Ответы (2 шт):
Я так понимаю просто нужно связать через API верхний с нижним, без обратного связывания?
Нижний слайдер стоит по центру, 4 мотоцикла в ряд, нижний слайдер меняется пли клике:
let bikeSwiper = new Swiper(".motorbike", {
slidesPerView: 4,
spaceBetween: 30,
})
let yearsSwiper = new Swiper(".years", {
centeredSlides: true,
slidesPerView: 3,
spaceBetween: 30,
})
let bike = document.querySelectorAll(".motorbike .swiper-slide")
bike.forEach(element => {
element.addEventListener("click", (event) => {
yearsSwiper.slideTo(event.target.dataset.id, 300)
})
})
body {
height: 100%;
}
.swiper {
margin-top: 20px;
}
.swiper-wrapper {
width: 100%;
height: 400px;
position: relative;
}
.swiper-slide {
width: 40%;
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
border: 1px solid black;
cursor: pointer;
}
<link href="https://unpkg.com/swiper@7/swiper-bundle.min.css" rel="stylesheet" />
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
<div class="motorbike swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" data-id="0">B1<br/>1980</div>
<div class="swiper-slide" data-id="0">B2<br/>1982</div>
<div class="swiper-slide" data-id="1">B3<br/>1985</div>
<div class="swiper-slide" data-id="2">B4<br/>1990</div>
<div class="swiper-slide" data-id="2">B5<br/>1992</div>
<div class="swiper-slide" data-id="3">B6<br/>1995</div>
<div class="swiper-slide" data-id="4">B7<br/>2000</div>
<div class="swiper-slide" data-id="5">B8<br/>2005</div>
</div>
</div>
<div class="years swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">1980 - 1984</div>
<div class="swiper-slide">1985 - 1989</div>
<div class="swiper-slide">1990 - 1994</div>
<div class="swiper-slide">1995 - 1999</div>
<div class="swiper-slide">2000 - 2004</div>
<div class="swiper-slide">2005 - 2009</div>
</div>
</div>
Но скорее всего вы хотите что то типа такого: один в ряд и автоматическая смена нижних слайдов при смене верхних.
let bikeSwiper = new Swiper(".motorbike", {
slidesPerView: 1,
spaceBetween: 30,
on: {
slideChange: (s) => {
yearsSwiper.slideTo(s.slides[s.activeIndex].dataset.id, 300)
}
}
})
let yearsSwiper = new Swiper(".years", {
centeredSlides: true,
slidesPerView: 3,
spaceBetween: 30,
})
* {
padding: 0;
margin: 0;
}
body {
height: 100%;
}
.swiper {
margin-top: 20px;
}
.swiper-wrapper {
width: 100%;
height: 400px;
position: relative;
}
.swiper-slide {
width: 80%;
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
border: 1px solid black;
cursor: pointer;
}
<link href="https://unpkg.com/swiper@7/swiper-bundle.min.css" rel="stylesheet" />
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
<div class="motorbike swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" data-id="0">B1<br/>1980</div>
<div class="swiper-slide" data-id="0">B2<br/>1982</div>
<div class="swiper-slide" data-id="1">B3<br/>1985</div>
<div class="swiper-slide" data-id="2">B4<br/>1990</div>
<div class="swiper-slide" data-id="2">B5<br/>1992</div>
<div class="swiper-slide" data-id="3">B6<br/>1995</div>
<div class="swiper-slide" data-id="4">B7<br/>2000</div>
<div class="swiper-slide" data-id="5">B8<br/>2005</div>
</div>
</div>
<div class="years swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">1980 - 1984</div>
<div class="swiper-slide">1985 - 1989</div>
<div class="swiper-slide">1990 - 1994</div>
<div class="swiper-slide">1995 - 1999</div>
<div class="swiper-slide">2000 - 2004</div>
<div class="swiper-slide">2005 - 2009</div>
</div>
</div>
Если почитать документацию по Методам и Событиям все становится достаточно просто.
Данные примеры можно как угодно масштабировать, главное придумать логику как получить id нужного слайда в соседнем слайдере
Обратите внимание в документации упоминается что если включить зацикливание слайдера то swiper.activeIndex индекс будет не совсем правильный, но есть параметр swiper.realIndex который поможет разобраться с индексами
После долгих экспериментов ответ был найден. Спасибо за помощь greg. Собственно, проблема заключалась в том, что слайды изображений генерировались через virtualSlides, а отследить их индекс не представляется возможным через методы API. Вот здесь я нашел человека, который столкнулся с такой же проблемой и воспользовался его решением. У каждого слайда с изображением мотоцикла есть дата атрибут с годом его производства, и у слайдов в ленте с годами у каждого слайда есть атрибут с годом.
- Нахожу активный слайд с моциком, считываю его дата атрибут.
- Прохожусь по ленте годов циклом, считываю атрибуты. Если дата атрибуты совпадают, нахожу индекс нужного года в ленте.
- Методом slideTo для ленты годов присваиваю новый активный слайд.
on: {
beforeTransitionStart: (e) => {
// Put in variable activeSlide the real active slide
let activeSlide;
let slides = e.slides;
slides.forEach(item => {
if (item.classList.contains("swiper-slide-active")) {
activeSlide = item;
}
});
// Find out dataset of the slide
let activeSlideYear = activeSlide.dataset.slide;
let stamps = document.querySelectorAll(".history__stamp");
stamps = Array.from(stamps);
// Put in variable targetStamp the real target stamp
let targetStamp;
stamps.forEach(item => {
if (item.dataset.target == activeSlideYear) {
targetStamp = item;
}
});
// Find out index of the target stamp
let targetStampIndex = stamps.indexOf(targetStamp);
if (targetStampIndex > 0) {
historyTimeline.slideTo(targetStampIndex);
}
}