最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Issue with slider centering on mobile: elements shift, duplicate, and lose alignment over time - Stack Overflow

programmeradmin2浏览0评论

I’m facing an issue with the slider on the mobile version of my site, and I can’t figure out what exactly is wrong. On the mobile version, the slides are not centering as they should. As a result, elements sometimes move to the side, and sometimes the slides are duplicated. Over time, the centering of the slides completely breaks, and they start behaving inconsistently.

On the desktop version, this is not as noticeable since the container takes up the full width of the screen, but on mobile, I just need the slide to be exactly in the center during both manual and auto scrolling. I just started learning JS.

What can I try next?

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> &lt;</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=".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=".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=".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=".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=".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=".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=".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=".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=".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=".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=".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=".png" alt="Icon">
      </div>
    </div>
  </div>
  <button class="scroll-button right"><span> &gt;</span></button>
</div>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论