JS实现无缝滚动轮播图

这是小刈同学第一次写博客(不会发表情包,还怎么滑稽起来呢),希望各路大神多多关照,多多交流,多多分享哈

工多熟练,第一次不知道直接上代码好不好,嗯嗯,好吧,那就直接上代码吧,此处有 懒人通道

说明:html结构,css样式基本可以略过,js部分都有注释,个人感觉注释看起来有点灰,那就先将就一下咯

用法:复制粘贴一把刷,在 carousel-item 里面爱干嘛干嘛,你懂的嘻嘻

1、HTML

<div class="container">
  <div class="carousel"> <!-- 轮播图容器carousel,溢出隐藏 -->
    <div class="carousel-inner"> <!-- 轮播图总宽度carousel-inner -->
      <div class="carousel-item">0</div> <!-- 左浮动 -->
      <div class="carousel-item">1</div>
      <div class="carousel-item">2</div>
      <div class="carousel-item">3</div>
      <div class="carousel-item">4</div>
    </div>
    <a class="carousel-btn carousel-pre-btn"></a> <!-- 定位,相对于carousel垂直居中 -->
    <a class="carousel-btn carousel-next-btn"></a>
    <ul class="carousel-indicators"> <!-- 相对于carousel定位,里面的内容水平居中text-align:center; -->
      <li class="current"></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </div>
</div>

2、CSS

* {
    margin: 0;
    padding: 0;
    user-select: none;
}

html,
body {
  height: 100%;
  background-color: gray;
}

.container {
  margin: 0 auto;
  width: 500px;
  height: 200px;
}

.carousel {
  position: relative;
  width: 500px;
  height: 200px;
  overflow: hidden;
}

.carousel-inner {
  position: relative;
  left: 0;
  /* 使用left属性实现过渡效果 */
  width: 2500px;
  height: 200px;
}

.carousel-item {
  width: 500px;
  height: 200px;
  float: left;
  font-size: 40px;
  font-weight: bold;
  text-align: center;
}

.carousel-item:nth-child(1) {
  background-color: pink;
}

.carousel-item:nth-child(2) {
  background-color: red;
}

.carousel-item:nth-child(3) {
  background-color: greenyellow;
}

.carousel-item:nth-child(4) {
  background-color: burlywood;
}

.carousel-item:nth-child(5) {
  background-color: rgb(133, 43, 168);
}

.carousel-btn {
  width: 50px;
  height: 50px;
  font-size: 40px;
  position: absolute;
  margin: auto 0;
  top: 0;
  bottom: 0;
  cursor: pointer;
}

.carousel-pre-btn {
  left: 0;
}

.carousel-next-btn {
  right: 0;
}

.carousel-indicators {
  list-style: none;
  width: 500px;
  height: 10px;
  position: absolute;
  bottom: 10px;
  text-align: center;
  font-size: 0;
  line-height: 0;
}

.carousel-indicators li {
  width: 10px;
  height: 10px;
  background-color: white;
  display: inline-block;
  border-radius: 50%;
  cursor: pointer;
  vertical-align: middle;
  margin-right: 10px;
}

.carousel-indicators li.current {
  background-color: black;
}

3、JS

推荐思路(文字不怎么重要,看码看注释)(滑稽表情.jpg):

第一:把点击按钮的事件做出来,先做点击下一张的感觉好做点,点一次滑动一次看看效果出来没有
第二:高亮圆点,在相对定位完成之后并且移动完成之后再重置index
第三:设置定时器
第四:点击圆点滚动至对应图片
第五:点击完一次,等图片滑动完成后再次点击才有效

let carousel = document.querySelector('.carousel') //获取carousel
    let carouselWidth = carousel.offsetWidth //获取carousel的宽度
    let carouselInner = document.querySelector('.carousel-inner') //获取需要移动位置的总大小
    let carouselItem = document.querySelectorAll('.carousel-item') //获取全部图片
    let carouselItemLength = carouselItem.length
    let preBtn = document.querySelector('.carousel-pre-btn') //获取向前的按钮
    let nextBtn = document.querySelector('.carousel-next-btn') //获取向后的按钮
    let indicatorsWrapper = document.querySelector('.carousel-indicators') //获取圆点容器
    let indicators = document.querySelectorAll('.carousel-indicators li') //获取所有圆点
    let indicatorsLength = indicators.length

    let index = 0 //定义图片索引
    let timmer = setTimeout(next, 2000) //设置定时器,定时滚动

    preBtn.addEventListener('click', () => {
      pre() //执行pre函数
      clearTimeout(timmer) //清除定时器
      preBtn.style.cssText = `pointer-events: none;` //为了不让用户不停的点击
      setTimeout(() => {
        preBtn.style.cssText = `pointer-events: auto;` //等滑动完一次之后恢复按钮
      }, 600);
    }, false)
    nextBtn.addEventListener('click', () => {
      next() //执行next函数
      clearTimeout(timmer)
      nextBtn.style.cssText = `pointer-events: none;`
      setTimeout(() => {
        nextBtn.style.cssText = `pointer-events: auto;`
      }, 600);
    }, false)

    //鼠标放上去停止滚动
    carousel.addEventListener('mouseenter', () => {
      clearTimeout(timmer)
    }, false)
    carousel.addEventListener('mouseleave', () => {
      timmer = setTimeout(next, 2000)
    }, false)

    //注意相对定位,注意相对定位,注意相对定位
    //向前滑动函数
    function pre() {
      indicators[index].classList.remove('current') //清除一开始高亮的圆点
      index-- //点击一次索引减一

      if (index < 0) { //如果索引小于第一张图片,将最后一张图片相对定位到第一张图片的前一张实现无缝滚动
        carouselItem[carouselItemLength - 1].style.cssText =
          `position: relative; left: ${-carouselWidth * carouselItemLength}px;` //定位的距离为全部图片的总长度
      }

      carouselInner.style.transition = `all 0.5s ease` //添加过渡效果,在css加过渡效果的话,轮播一次之后会被下面那个transition:none;覆盖,所以在这里加过渡
      carouselInner.style.left = `${-carouselWidth * index}px` //过渡偏移的距离

      currentIndicator() //如果写在transitionend里面,高亮会跟不上速度

      carouselInner.addEventListener('transitionend', () => { //transitionend事件下才有无缝滚动效果
        if (index === carouselItemLength - 1) {
          carouselInner.style.transition = `none` //取消过渡
          carouselInner.style.left = `${-carouselWidth * index}px` //将偏移量重置
          carouselItem[carouselItemLength - 1].style.cssText = `position: relative; left: 0;` //将最后一张图片位置重置
        }
      }, false)

      timmer = setTimeout(next, 2000) //添加定时器
    }
    //向后滑动函数
    function next() {
      indicators[index].classList.remove('current')
      index++ //点击一次索引加一

      if (index > carouselItemLength - 1) { //如果索引大于最后一张图片,将第一张图片相对定位到最后一张的下一张实现无缝滚动
        carouselItem[0].style.cssText = `position: relative; left: ${carouselWidth * carouselItemLength}px;` //定位的距离为全部图片的总长度
      }

      carouselInner.style.transition = `all 0.5s ease` //添加过渡效果,在css加过渡效果的话,轮播一次之后会被下面那个transition:none;覆盖,所以在这里加过渡
      carouselInner.style.left = `${-carouselWidth * index}px` //过渡偏移的距离

      currentIndicator()

      carouselInner.addEventListener('transitionend', () => { //transitionend事件下才有无缝滚动效果
        if (index === 0) {
          carouselInner.style.transition = `none` //取消过渡
          carouselInner.style.left = `${-carouselWidth * index}px` //将偏移量重置
          carouselItem[0].style.cssText = `position: relative; left: 0;` //将第一张图片位置重置
        }
      }, false)

      timmer = setTimeout(next, 2000) //添加定时器
    }
    //定义当前高亮圆点函数
    function currentIndicator() { 
      if (index < 0) { //如果索引小于第一张图片,索引重置为carouselItemLength - 1,即最后一张
        index = carouselItemLength - 1
      }
      if (index > carouselItemLength - 1) { //如果索引大于最后一张图片,索引重置为0,即第一张
        index = 0
      }
      indicators[index].classList.add('current')
    }
    //点击圆点滚动至对应图片
    function clickIndicator() {
      indicatorsWrapper.addEventListener('click', (e) => { //事件委托
        let target = e.target
        while (target !== indicatorsWrapper) { //target不是父元素时进入循环
          if (target.nodeName.toLowerCase() === 'li') { //判断target是否为li
            indicators[index].classList.remove('current') //清除一开始高亮的圆点
            for (let i = 0; i < indicatorsLength; i++) {
              if (indicators[i] === target) { //获取点击的li的索引
                index = i
              }
            }
            carouselInner.style.transition = `all 0.5s ease`
            carouselInner.style.left = `${-carouselWidth * index}px`
            target.classList.add('current') //target高亮
            break
          }
          target = target.parentNode //如果点击的不是li元素,向上取其父元素,直到target==li为止
        }
        return
      }, false)
    }
    clickIndicator()

4、总结

嗯嗯,说到总结嘛,就是……………………(°_°)……………………(°_°)

先写HTML结构,然后再写CSS,写出你想要的外观,最后再写JS咯哈哈,JS上面就有推荐的思路啦!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
附加:无注释版本+详解版

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值