Swiper JS Pagination
Подскажите пожалуйста, как сделать, что-бы булеты были бесконечны, а активный булет всегда был по центру, как на этой картинке.
А также, можно ли задать, чтобы отображалось конкретное число булетов, например 7, в центре активный и от него по бокам 3.
Не важно какой слайд по счету идет, активный булет всегда в центре.
slidesPerView: 1,
spaceBetween: 30,
centeredSlides: true,
loop: true,
pagination: {
el: ".swiper-pagination",
dynamicBullets: true,
},
На оф. сайте не смог найти информацию.
Ответы (1 шт):
Автор решения: Dev18
→ Ссылка
Насколько мне известно, параметр dynamicBullets в Swiper делает активный булет крупнее, но не центрирует его.
Также в Swiper нет встроенного режима, который делает "виртуальные" булеты и всегда держит активный по центру, как в примере на вашем изображении.
Чтобы реализовать такой эффект, предложу такой вариант:
- оставляем значение по умолчанию
pagination: false,- создаём собственный DOM-блок с булетами,
- и при каждом переключении слайда обновлять эти булеты вручную так, чтобы активный оставался по центру.
- это кастомное решение, поэтому при изменении количества слайдов, стоит тестировать
const BULLETS_TO_SHOW = 7;
const BULLETS_SIDE = Math.floor(BULLETS_TO_SHOW / 2);
const swiper = new Swiper('.swiper', {
slidesPerView: 'auto',
centeredSlides: true,
spaceBetween: 30,
loop: true,
on: {
init(swiper) {
updateBullets(swiper);
},
slideChange(swiper) {
updateBullets(swiper);
},
}
});
function updateBullets(swiperInstance) {
const totalSlides = swiperInstance.slides.length - swiperInstance.loopedSlides * 2;
const realIndex = swiperInstance.realIndex;
const container = document.querySelector('.custom-pagination');
container.innerHTML = '';
for (let i = -BULLETS_SIDE; i <= BULLETS_SIDE; i++) {
let bulletIndex = (realIndex + i + totalSlides) % totalSlides;
const bullet = document.createElement('span');
bullet.className = 'custom-bullet';
if (i === 0) bullet.classList.add('active');
bullet.addEventListener('click', () => {
swiperInstance.slideToLoop(bulletIndex);
});
container.appendChild(bullet);
}
}
.swiper {
width: 100%;
max-width: 700px;
height: 350px;
margin: auto;
}
.swiper-slide {
width: 80%;
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.swiper-slide img {
width: 100%;
height: auto;
border-radius: 12px;
}
.custom-pagination {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 20px;
}
.custom-bullet {
width: 10px;
height: 10px;
background: #ccc;
border-radius: 50%;
transition: all 0.3s ease;
cursor: pointer;
}
.custom-bullet.active {
background: #007aff;
transform: scale(1.5);
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide"><img src="https://i.sstatic.net/8en8F8TK.png" alt="1"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/IxdomiLW.png" alt="2"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/2ffgSLzM.png" alt="3"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/oTvahlCA.png" alt="4"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/yrLQxCB0.png" alt="5"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/Lu5xevdr.png" alt="6"></div>
<div class="swiper-slide"><img src="https://i.sstatic.net/mLdQWkFD.png" alt="7"></div>
</div>
</div>
<div class="custom-pagination"></div>
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
