Проблема с слайдером на мобильной версии: слайды не центрируются, иногда дублируются и со временем сбивается автоскролл и позиционирование
У меня возникла проблема с слайдером на мобильной версии сайта, и я не могу понять, в чем именно заключается ошибка. На мобильной версии слайды не центрируются как нужно. В результате, элементы иногда уезжают в сторону, а иногда слайды дублируются. При этом через некоторое время центрирование слайдов вообще сбивается, и слайды начинают вести себя нестабильно, на десктоп версии это не особо ощутимо т.к. контейнер на всю ширину экрана,а в мобильной версии мне просто нужно что бы при ручном и авто скролле слайд был ровно по центру. Я только начал изучать JS, поэтому не могу разобраться,уже 2 дня потратил, буду рад вашей помощи!
document.addEventListener("DOMContentLoaded", function() {
const wrapper = document.querySelector(".wrapper");
const slides = Array.from(wrapper.children);
const leftButton = document.querySelector(".scroll-button.left");
const rightButton = document.querySelector(".scroll-button.right");
function getSlideWidth() {
const slide = slides[0]; // Первый слайд
const style = window.getComputedStyle(slide);
const marginRight = parseInt(style.marginRight, 10) || 0; // Учитываем отступ между слайдами
return slide.getBoundingClientRect().width + marginRight;
}
const slideWidth = getSlideWidth();
// Дублируем слайды для бесконечного скролла
slides.forEach(slide => {
const cloneStart = slide.cloneNode(true);
const cloneEnd = slide.cloneNode(true);
wrapper.appendChild(cloneEnd); // Дублируем в конец
wrapper.insertBefore(cloneStart, wrapper.firstChild); // Дублируем в начало
});
const originalSlidesCount = slides.length;
wrapper.scrollLeft = originalSlidesCount * slideWidth;
// Корректировка положения
function correctScrollPosition() {
const maxScrollLeft = (originalSlidesCount * 2 - 1) * slideWidth;
if (wrapper.scrollLeft < originalSlidesCount * slideWidth - slideWidth / 2) {
wrapper.scrollLeft += originalSlidesCount * slideWidth;
} else if (wrapper.scrollLeft > maxScrollLeft + slideWidth / 2) {
wrapper.scrollLeft -= originalSlidesCount * slideWidth;
}
}
// Прокрутка влево
leftButton.addEventListener("click", function() {
const targetScrollLeft = wrapper.scrollLeft - slideWidth;
wrapper.scrollTo({
left: targetScrollLeft,
behavior: "smooth",
});
setTimeout(correctScrollPosition, 300); // Исправляем после анимации
});
// Прокрутка вправо
rightButton.addEventListener("click", function() {
const targetScrollLeft = wrapper.scrollLeft + slideWidth;
wrapper.scrollTo({
left: targetScrollLeft,
behavior: "smooth",
});
setTimeout(correctScrollPosition, 300); // Исправляем после анимации
});
// Корректируем позицию при ручной прокрутке
wrapper.addEventListener("scroll", () => {
clearTimeout(wrapper.isScrolling);
wrapper.isScrolling = setTimeout(correctScrollPosition, 100);
});
// Автоскролл
const intervalTime = 5000; // Интервал в миллисекундах
let autoScroll = setInterval(() => {
const targetScrollLeft = wrapper.scrollLeft + slideWidth;
wrapper.scrollTo({
left: targetScrollLeft,
behavior: "smooth",
});
setTimeout(correctScrollPosition, 300); // Исправляем после анимации
}, intervalTime);
// Остановка автоскролла при наведении мыши
wrapper.addEventListener("mouseenter", () => clearInterval(autoScroll));
// Возобновление автоскролла при убирании мыши
wrapper.addEventListener("mouseleave", () => {
autoScroll = setInterval(() => {
const targetScrollLeft = wrapper.scrollLeft + slideWidth;
wrapper.scrollTo({
left: targetScrollLeft,
behavior: "smooth",
});
setTimeout(correctScrollPosition, 300);
}, intervalTime);
});
});
.scroll-container {
display: flex;
margin-bottom: 15px;
align-items: center;
gap: 10px;
width: 100%;
position: relative;
}
.wrapper {
display: flex;
overflow-x: scroll;
gap: 10px;
padding: 10px;
border-radius: 10px;
width: 100%;
overflow-y: hidden;
/* Скрываем полосу прокрутки */
-ms-overflow-style: none;
scrollbar-width: none;
}
.wrapper::-webkit-scrollbar {
display: none;
/* Chrome, Safari и Opera */
}
.content-item {
flex: 0 0 608px;
/* Фиксированная ширина слайда */
height: 200px;
/* Высота слайда */
background-color: #f0f0f0;
position: relative;
/* Для позиционирования заголовка */
color: #fff;
text-align: left;
padding: 20px;
display: flex;
box-sizing: border-box;
flex-direction: column;
justify-content: flex-end;
background-size: cover;
/* Адаптация фонового изображения */
background-position: center;
background-repeat: no-repeat;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
/* Лёгкая тень */
}
.content-text {
display: flex;
flex-direction: column;
justify-content: flex-start;
position: relative;
z-index: 1;
word-wrap: break-word;
overflow-wrap: break-word;
white-space: normal;
max-width: 80%;
}
.content-text h2 {
margin: 0 0 10px 0;
font-size: 18px;
font-weight: bold;
color: #333333;
}
.content-text p {
margin: 0;
font-size: 14px;
color: #666666;
line-height: 1.4;
}
.scroll-button {
background-color: transparent;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
position: absolute;
z-index: 10;
border: none
}
.scroll-button.left {
left: 10px;
top: 50%;
transform: translateY(-50%);
}
.scroll-button.right {
right: 10px;
top: 50%;
transform: translateY(-50%);
}
.scroll-button span {
font-size: 18px;
font-weight: bold;
color: #333;
}
.scroll-button:hover {
background-color: #f8f9fa;
}
.scroll-button:active {
background-color: #e2e6ea;
}
.scroll-button::after {
content: '';
position: absolute;
inset: 0;
border-radius: 0;
box-shadow: none;
}
.icon-container {
position: absolute;
/* Абсолютное позиционирование */
top: 50%;
/* Центрируем по вертикали */
right: 20px;
/* Отступ от правого края */
transform: translateY(-50%);
/* Корректируем вертикальное центрирование */
}
.icon-container img {
width: 160px;
/* Размер иконки */
height: 160px;
object-fit: contain;
/* Сохраняем пропорции */
}
}
@media (max-width: 768px) {
.wrapper {
overflow-x: scroll;
/* Отключаем горизонтальную прокрутку */
}
.content-item {
flex: 0 0 100%;
/* Слайд занимает 100% ширины экрана */
height: 200px;
/* Задайте нужную высоту */
margin-right: 0;
/* Убираем отступы между слайдами */
}
}
@media (max-width: 500px) {
.category-item img {
scale: 1.5
}
}
@media (max-width: 768px) {
.scroll-container {
overflow: hidden;
position: relative
}
.content-item {
flex: 0 0 90%;
/* Слайды занимают 90% ширины экрана */
height: 150px;
/* Уменьшаем высоту для мобильных */
}
.wrapper {
gap: 5px;
/* Уменьшаем отступы между слайдами */
padding: 5px;
/* Сужаем внутренние отступы */
}
}
@media (max-width: 480px) {
.content-item {
flex: 0 0 95%;
/* Слайды занимают почти всю ширину экрана */
height: 120px;
/* Ещё меньше высота для маленьких экранов */
}
.icon-container img {
width: 100px;
height: 100px;
object-fit: contain;
}
}
@media (max-width: 768px) {
.wrapper {
display: flex;
justify-content: start;
align-items: center;
overflow-x: auto;
scroll-behavior: smooth;
}
.wrapper::-webkit-scrollbar {
display: none;
}
.scroll-button {
display: none;
}
}
<div class="scroll-container">
<button class="scroll-button left"><span> <</span></button>
<div class="wrapper">
<div class="content-item" style="background-color:#EBD8F4">
<div class="content-text">
<h2>Osalege konkursil</h2>
<p>Saage võitjaks ja võitke väärtuslikke auhindu!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/cup.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#ADD2FF">
<div class="content-text">
<h2>Postitage kuulutusi</h2>
<p>Rääkige maailmale oma toodetest ja teenustest!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/pen.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#FEEE99">
<div class="content-text">
<h2>Turvalisuse juhend</h2>
<p>Kuidas vältida petuskeeme?</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/security.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#F3E1D7">
<div class="content-text">
<h2>Vaheta oma kaup</h2>
<p>Vaheta vana uue vastu — lihtsalt ja mugavalt!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/exchange.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#F3E1D7">
<div class="content-text">
<h2>Vaheta oma kaup</h2>
<p>Vaheta vana uue vastu — lihtsalt ja mugavalt!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/exchange.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#FEEE99">
<div class="content-text">
<h2>Turvalisuse juhend</h2>
<p>Kuidas vältida petuskeeme?</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/security.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#ADD2FF">
<div class="content-text">
<h2>Postitage kuulutusi</h2>
<p>Rääkige maailmale oma toodetest ja teenustest!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/pen.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#EBD8F4">
<div class="content-text">
<h2>Osalege konkursil</h2>
<p>Saage võitjaks ja võitke väärtuslikke auhindu!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/cup.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#F3E1D7">
<div class="content-text">
<h2>Vaheta oma kaup</h2>
<p>Vaheta vana uue vastu — lihtsalt ja mugavalt!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/exchange.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#FEEE99">
<div class="content-text">
<h2>Turvalisuse juhend</h2>
<p>Kuidas vältida petuskeeme?</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/security.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#ADD2FF">
<div class="content-text">
<h2>Postitage kuulutusi</h2>
<p>Rääkige maailmale oma toodetest ja teenustest!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/pen.png" alt="Icon">
</div>
</div>
<div class="content-item" style="background-color:#EBD8F4">
<div class="content-text">
<h2>Osalege konkursil</h2>
<p>Saage võitjaks ja võitke väärtuslikke auhindu!</p>
</div>
<div class="icon-container">
<img src="https://h2h.ee/assets/img/icons_slider/cup.png" alt="Icon">
</div>
</div>
</div>
<button class="scroll-button right"><span> ></span></button>
</div>