likes
comments
collection
share

原生JS实现轮播图

作者站长头像
站长
· 阅读数 19

前言

轮播图是一个常见的组件,今天我们使用原生JavaScript来实现。

先来看看效果图:

原生JS实现轮播图

实现

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>轮播图</title>
  <link rel="stylesheet" href="./css/index.css" />"
</head>
<body>
  <div class="container">
    <div class="carousel">
      <div class="item"><a href=""><img src="./img/1.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/2.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/3.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/4.jpg" alt=""></a></div>
    </div>
    <div class="indicator">
      <span class="active"></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>
  <script src="./js/index.js"></script>
</body>
</html>

css/index.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.container {
  width: 500px;
  height: 300px;
  margin: 10px auto;
  overflow: hidden;
  position: relative;
}
.carousel {
  width: 100%;
  height: 100%;
  display: flex;
  transition: all .5s;
}
.carousel img {
  width: 500px;
  height: 300px;
}
.indicator {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
}
.indicator span {
  width: 12px;
  height: 12px;
  border: 2px solid #ccc;
  border-radius: 50%;
  margin: 0 3px;
}
.indicator span.active {
  background: #fff;
  border-color: #fff;
}

js/index.js

const query = (el) => {
  return document.querySelector(el)
}
const queryAll = (el) => {
  return document.querySelectorAll(el)
}
const doms = {
  carousel: query('.carousel'),
  indicators: queryAll('.indicator span')
}
let curIndex = 0
function moveTo(index) {
  doms.carousel.style.transform = `translateX(-${index * 100}%)`
  const active = query('.indicator .active')
  active.classList.remove('active')
  doms.indicators[index].classList.add('active')
  curIndex = index
}

function initEvents() {
  doms.indicators.forEach((item, index) => {
    item.onclick = () => {
      moveTo(index)
    }
  })
}
initEvents()

这样,就实现了一个简单的轮播图

原生JS实现轮播图

完善

接下来,我们来完善这个轮播图的功能,加上左右切换并实现无缝切换。

  1. index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>轮播图</title>
  <link rel="stylesheet" href="./css/index.css" />"
</head>
<body>
  <div class="container">
    <div class="carousel">
      <div class="item"><a href=""><img src="./img/1.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/2.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/3.jpg" alt=""></a></div>
      <div class="item"><a href=""><img src="./img/4.jpg" alt=""></a></div>
    </div>
    <div class="arrow arrow-left">&lt;</div>
    <div class="arrow arrow-right">&gt;</div>
    <div class="indicator">
      <span class="active"></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>
  <script src="./js/index.js"></script>
</body>
</html>
  1. css/index.css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.container {
  width: 500px;
  height: 300px;
  margin: 10px auto;
  overflow: hidden;
  position: relative;
}
.carousel {
  width: 100%;
  height: 100%;
  display: flex;
  transition: all .5s;
}
.carousel img {
  width: 500px;
  height: 300px;
}
.indicator {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
}
.indicator span {
  width: 12px;
  height: 12px;
  border: 2px solid #ccc;
  border-radius: 50%;
  margin: 0 3px;
}
.indicator span.active {
  background: #fff;
  border-color: #fff;
}
.arrow {
  position: absolute;
  width: 40px;
  height: 40px;
  background-color: red;
  top: 50%;
  transform: translateY(-50%);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.2);
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}
.arrow-left {
  left: 10px;
}
.arrow-right {
  right: 10px;
}
  1. js/index.js
const query = (el) => {
  return document.querySelector(el)
}
const queryAll = (el) => {
  return document.querySelectorAll(el)
}
const doms = {
  carousel: query('.carousel'),
  indicators: queryAll('.indicator span'),
  leftArrow: query('.arrow-left'),
  rightArrow: query('.arrow-right'),
}
const count = doms.indicators.length
let curIndex = 0
function moveTo(index) {
  doms.carousel.style.transform = `translateX(-${index * 100}%)`
  const active = query('.indicator .active')
  active.classList.remove('active')
  doms.indicators[index].classList.add('active')
  curIndex = index
}
function toLeft() {
  if (curIndex === 0) {
    console.log('无缝切换')
  } else {
    moveTo(curIndex - 1)
  }
}
function toRight() {
  if (curIndex === count - 1) {
    console.log('无缝切换')
  } else {
    moveTo(curIndex + 1)
  }
}
function initEvents() {
  doms.indicators.forEach((item, index) => {
    item.onclick = () => {
      moveTo(index)
    }
  })
  doms.leftArrow.onclick = () => toLeft()
  doms.rightArrow.onclick = () => toRight()
}
initEvents()

接下来,实现无缝切换。

原生JS实现轮播图

将第一张图放到末尾,将最后一张图放到开头

原生JS实现轮播图

  • 第一种情况:当轮播图到最后一张图,需要右切换时: 我们直接把当前位置切换为开头的图,然后再切换到第(0)张图

原生JS实现轮播图

  • 第二种情况:当轮播图到第一张图,需要左切换时: 我们直接把当前位置切换为开头的图,然后再切换到第(0)张图

原生JS实现轮播图

js/index.js

const query = (el) => {
  return document.querySelector(el)
}
const queryAll = (el) => {
  return document.querySelectorAll(el)
}
const doms = {
  carousel: query('.carousel'),
  indicators: queryAll('.indicator span'),
  leftArrow: query('.arrow-left'),
  rightArrow: query('.arrow-right'),
}
const count = doms.indicators.length
let curIndex = 0
function moveTo(index) {
  doms.carousel.style.transform = `translateX(-${index * 100}%)`
  doms.carousel.style.transition = 'all .5s'
  const active = query('.indicator .active')
  active.classList.remove('active')
  doms.indicators[index].classList.add('active')
  curIndex = index
}
function toLeft() {
  if (curIndex === 0) {
    doms.carousel.style.transform = `translateX(-${count * 100}%)`
    doms.carousel.style.transition = 'none'
    // 这里添加强制渲染是为了有过渡效果
    doms.carousel.clientWidth // 强制渲染
    moveTo(count - 1)
  } else {
    moveTo(curIndex - 1)
  }
}
function toRight() {
  if (curIndex === count - 1) {
    doms.carousel.style.transform = `translateX(100%)`
    doms.carousel.style.transition = 'none'
    // 这里添加强制渲染是为了有过渡效果
    doms.carousel.clientWidth // 强制渲染
    moveTo(0)
  } else {
    moveTo(curIndex + 1)
  }
}
function initEvents() {
  doms.indicators.forEach((item, index) => {
    item.onclick = () => {
      moveTo(index)
    }
  })
  doms.leftArrow.onclick = () => toLeft()
  doms.rightArrow.onclick = () => toRight()
}
function initCarousel() {
  // 复制第一张图
  const first = doms.carousel.firstElementChild.cloneNode(true)
  // 复制最后一张图
  const last = doms.carousel.lastElementChild.cloneNode(true)
  // 将第一张图复制到末尾
  doms.carousel.appendChild(first)
  // 将最后一张图复制到开头
  doms.carousel.insertBefore(last, doms.carousel.firstElementChild)
  // 需要看到仍是第一张图
  // 设置最后一张复制图为绝对定位
  last.style.position = "absolute"
  last.style.transform = `translateX(-100%)`
}
initCarousel()
initEvents()

效果图:

原生JS实现轮播图

转载自:https://juejin.cn/post/7254834316018303033
评论
请登录