返回

轮播组件踩坑之旅

前端

用AI螺旋创作器打造一个专业级的技术博客

由于先后采用了两种实现方式,第二种是在第一种的基础上进行优化(事实上,第一种并没有做完),因此分开来讲解。

图中红线区域即是我们文章的视口(其他图片将会被隐藏)。这个轮播只展示 5 张图片,但是它的首尾各还有两张图片,在图 1 前面放置了图 5,在图 5 后面放置了图 1。

之所以这么做,是为了实现无限滚动。

起初,我直接将 5 张图片放入容器中,并使用 CSS 实现了轮播的效果,如下所示:

.container {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.images {
  width: 500%;
  height: 100%;
  display: flex;
  transform: translateX(-20%);
  animation: slide 10s infinite;
}

@keyframes slide {
  0% {
    transform: translateX(-20%);
  }
  20% {
    transform: translateX(-40%);
  }
  40% {
    transform: translateX(-60%);
  }
  60% {
    transform: translateX(-80%);
  }
  80% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(-120%);
  }
}

这种方法虽然可以实现轮播效果,但存在一些问题:

  • 图片间距不均匀: 由于图片是在容器中直接并排放置的,因此图片之间的间距是不均匀的。
  • 动画不流畅: 当轮播到最后一幅图片时,动画会突然跳回到第一幅图片,造成不流畅的视觉效果。
  • 无法实现无限滚动: 这种方法无法实现无限滚动,因为当轮播到最后一幅图片时,无法再继续轮播。

为了解决这些问题,我采用了第二种实现方式:

<div class="container">
  <div class="images-wrapper">
    <div class="images">
      <img src="image1.jpg" alt="Image 1">
      <img src="image2.jpg" alt="Image 2">
      <img src="image3.jpg" alt="Image 3">
      <img src="image4.jpg" alt="Image 4">
      <img src="image5.jpg" alt="Image 5">
    </div>
  </div>
  <button class="prev-btn">Prev</button>
  <button class="next-btn">Next</button>
</div>
.container {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.images-wrapper {
  width: calc(100% + 80%);
  height: 100%;
  margin-left: -40%;
}

.images {
  width: 500%;
  height: 100%;
  display: flex;
  transform: translateX(-20%);
}

.prev-btn, .next-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  padding: 10px 20px;
  background-color: #fff;
  border: 1px solid #000;
}

.prev-btn {
  left: 10px;
}

.next-btn {
  right: 10px;
}
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const images = document.querySelector('.images');
const imagesWrapper = document.querySelector('.images-wrapper');
let currentImage = 0;

prevBtn.addEventListener('click', () => {
  currentImage--;
  if (currentImage < 0) {
    currentImage = 4;
  }
  images.style.transform = `translateX(-${currentImage * 20}%)`;
});

nextBtn.addEventListener('click', () => {
  currentImage++;
  if (currentImage > 4) {
    currentImage = 0;
  }
  images.style.transform = `translateX(-${currentImage * 20}%)`;
});

这种方法解决了上述问题:

  • 图片间距均匀: 通过在容器中放置一个额外的 div 来包裹图片,可以使图片之间的间距均匀。
  • 动画流畅: 通过使用 JavaScript 来控制动画,可以实现流畅的轮播效果。
  • 实现无限滚动: 通过在轮播到最后一幅图片时将 currentImage 重置为 0,可以实现无限滚动。

总的来说,编写轮播组件需要考虑多个因素,包括图片间距、动画流畅度和无限滚动的实现。通过使用合理的 HTML、CSS 和 JavaScript,可以实现一个功能完善、用户体验良好的轮播组件。