纯js手搓轮播图


纯js手搓轮播图,平滑过渡动画,首尾无缝衔接

代码

HTML

< >

CSS

.swiper {
  width: 1200px;
  height: 500px;
  margin: 50px auto;
  position: relative;
  overflow: hidden;
}

.swiper-img {
  position: absolute;
  top: 0;
  left: 0px;
  width: 100%;
  height: 100%;
  display: flex;
  transition: 0.5s ease;
}

.swiper-img img {
  width: 100%;
  height: 100%;
}

.swiper-point {
  position: absolute;
  bottom: 5px;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
}

.swiper-point li {
  cursor: pointer;
  list-style: none;
  width: 40px;
  height: 4px;
  margin: 5px;
  border-radius: 2px;
  /* background-color: rgba(255,255,255,.8); */
  background-color: #9f9f9f;
  transition: 0.3s ease;
}

.swiper-point li:hover {
  background-color: #3498db;
}

.swiper-point li.active {
  background-color: #fff;
}

.swiper span {
  user-select: none;
  cursor: pointer;
  display: block;
  position: absolute;
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 50px;
  font-size: 20px;
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  border-radius: 50%;
}

.left-btn {
  top: 45%;
  left: 10px;
}

.right-btn {
  top: 45%;
  right: 10px;
}

JS

修改图片宽度的话,需要把js里ImgWidth改成想要的宽度

// 获取图片列表
const swiperImg = document.querySelector(".swiper-img");
// 获取li列表
const lis = document.querySelectorAll(".swiper-point li");
// 图片宽度
const imgWidth = 1200;
// 获取按钮
const leftBtn = document.querySelector(".left-btn");
const rightBtn = document.querySelector(".right-btn");
// 克隆第一张图片,添加到图片列表的最后
let cloneImg = swiperImg.firstElementChild.cloneNode();
swiperImg.appendChild(cloneImg);

let index = 0; //图片的坐标

let lock = true; //设置节流

let timer = null; //设置定时器

// 单击事件
rightBtn.onclick = () => {
  // 判断锁的状态,如果是关闭就直接return
  if (!lock) return;
  // 移动位置
  index++;
  // 给下面去掉动画重新加上动画
  swiperImg.style.transition = ".5s ease";
  // 当坐标等于最后一张图片时
  if (index === swiperImg.children.length - 1) {
    // 迅速切换到第一张图片
    setTimeout(() => {
      swiperImg.style.left = 0;
      index = 0;
      changeLi(index);
      // 取消过渡动画,无缝衔接第一张图片
      swiperImg.style.transition = "none";
    }, 500);
  }
  swiperImg.style.left = `${-index * imgWidth}px`;
  if (index < swiperImg.children.length - 1) {
    changeLi(index);
  }
  // 关锁
  lock = false;
  // 500毫秒后开锁
  setTimeout(() => {
    lock = true;
  }, 500);
};

// 改变li的样式
function changeLi(index) {
  lis.forEach((li) => {
    if (li.classList.contains("active")) {
      li.classList.remove("active");
    }
  });
  lis[index].classList.add("active");
}

// 左击事件
leftBtn.onclick = () => {
  // 判断锁的状态,如果是关闭就直接return
  if (!lock) return;
  // 如果现在是第一张图片时
  if (index === 0) {
    // 切换到克隆的图片
    swiperImg.style.left = `${-(swiperImg.children.length - 1) * imgWidth}px`;

    // 取消动画,瞬间过去
    swiperImg.style.transition = "none";
    setTimeout(() => {
      // 真正的最后一张图
      index = swiperImg.children.length - 2;
      changeLi(index);
      // 加上动画
      swiperImg.style.transition = ".5s ease";
      swiperImg.style.left = `${-index * imgWidth}px`;
    });
  } else {
    index--;
    swiperImg.style.left = `${-index * imgWidth}px`;
    changeLi(index);
  }
  // 关锁;
  lock = false;
  // 500毫秒后开锁
  setTimeout(() => {
    lock = true;
  }, 500);
};

// li点击事件
lis.forEach((li, idx) => {
  li.onclick = () => {
    index = idx
    swiperImg.style.left = `${-index * imgWidth}px`;
    changeLi(index)
  }
})

// 轮播方法
function auto() {
  // leftBtn.click();
  rightBtn.click();
}
// 定时轮播
timer = setInterval(() => {
  auto();
}, 3000);

swiperImg.onmouseover = () => {
  clearInterval(timer);
};

swiperImg.onmouseout = () => {
  timer = setInterval(() => {
    auto();
  }, 3000);
};