三十的博客

渡一教育:无限轮播

发布时间
阅读量 加载中...

实现效果

此演示仅在桌面端浏览器中可用

html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="carousel-container">
      <div class="carousel-list">
        <div class="carousel-item item-1"></div>
        <div class="carousel-item item-2"></div>
        <div class="carousel-item item-3"></div>
      </div>
      <div class="carousel-arrow carousel-arrow-left"></div>
      <div class="carousel-arrow carousel-arrow-right"></div>
      <div class="indicator">
        <span class="active"></span>
        <span></span>
        <span></span>
      </div>
    </div>
    <script src="./index.js"></script>
  </body>
</html>

css

css
.carousel-container {
  width: 500px;
  height: 300px;
  margin: 20px auto;
  position: relative;
  outline: 10px solid #000;
  overflow: hidden;
}

.carousel-list {
  width: 100%;
  height: 100%;
  display: flex;
  position: relative;
  z-index: -1;
}

.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid rgba(255, 255, 255, 0.3);
  opacity: 0.9;
  z-index: 10;
}

.carousel-arrow:hover {
  background: rgba(0, 0, 0, 0.8);
  transform: translateY(-50%) scale(1.05);
  border-color: rgba(255, 255, 255, 0.6);
  opacity: 1;
}

.carousel-arrow:active {
  transform: translateY(-50%) scale(0.95);
}

.carousel-arrow::before {
  content: "";
  width: 12px;
  height: 12px;
  border-left: 3px solid #fff;
  border-bottom: 3px solid #fff;
  position: absolute;
  transition: all 0.3s ease;
}

.carousel-arrow-left {
  left: 20px;
}

.carousel-arrow-right {
  right: 20px;
}

.carousel-arrow-left::before {
  transform: translateX(4px) rotate(45deg);
}

.carousel-arrow-right::before {
  transform: translateX(-4px) rotate(-135deg);
}

.carousel-arrow:hover::before {
  border-color: #fff;
  filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.8));
}

.indicator {
  display: flex;
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
}

.indicator span.active {
  border-color: #fff;
  background: #fff;
}

.indicator span {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid #ccc;
  margin: 0 3px;
  cursor: pointer;
}

.carousel-item.item-1 {
  background: #c82828;
}

.carousel-item.item-2 {
  background: #d88d2b;
}

.carousel-item.item-3 {
  background: #28c840;
}

.carousel-item {
  height: 100%;
  flex: 0 0 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 60px;
  color: #000;
  font-weight: bold;
  text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.5);
}

.carousel-item.item-1::after {
  content: "1";
}
.carousel-item.item-2::after {
  content: "2";
}
.carousel-item.item-3::after {
  content: "3";
}

js

js
const doms = {
  carouselList: document.querySelector(".carousel-list"),
  arrowLeft: document.querySelector(".carousel-arrow-left"),
  arrowRight: document.querySelector(".carousel-arrow-right"),
  indicators: document.querySelectorAll(".indicator span"),
};

const count = doms.indicators.length; // 轮播图的数量
let curIndex = 0; // 当前显示的图片索引
function moveTo(index) {
  doms.carouselList.style.transform = `translateX(${-index * 100}%)`;
  doms.carouselList.style.transition = "transform 0.5s";
  // 设置指示器
  doms.indicators.forEach((indicator, i) => {
    indicator.className = i === index ? "active" : "";
  });
  curIndex = index;
}

doms.indicators.forEach((indicator, index) => {
  indicator.onclick = () => {
    moveTo(index);
  };
});

function init() {
  const firstCloned = doms.carouselList.firstElementChild.cloneNode(true);
  const lastCloned = doms.carouselList.lastElementChild.cloneNode(true);
  doms.carouselList.appendChild(firstCloned);
  doms.carouselList.insertBefore(
    lastCloned,
    doms.carouselList.firstElementChild
  );
  lastCloned.style.marginLeft = "-100%";
}

init();

function left() {
  if (curIndex === 0) {
    doms.carouselList.style.transition = "none";
    doms.carouselList.style.transform = `translateX(${-count * 100}%)`;
    // 让浏览器渲染 同步的方式
    doms.carouselList.clientWidth;
    moveTo(count - 1);
  } else {
    moveTo(curIndex - 1);
  }
}

function right() {
  if (curIndex === count - 1) {
    doms.carouselList.style.transition = "none";
    doms.carouselList.style.transform = `translateX(100%)`;
    // 让浏览器渲染 同步的方式
    doms.carouselList.clientWidth;
    moveTo(0);
  } else {
    moveTo(curIndex + 1);
  }
}

doms.arrowLeft.onclick = left;
doms.arrowRight.onclick = right;
#渡一教育 #Before伪元素