2025/6/22 原生js实现图片carousel跑马灯和思路整理

仅作个人复习梳理用

一、效果

        加了三倍速才压成gif

二、HTML格式

        还是从HTML的布局开始考虑一个carousel里有什么

        大盒子装整个跑马灯的元素

        |——拼接图片列表的容器

        |——左右切换按键

        这里拼接图片列表注意:要把最后一张照片复制到最前面保证第一张图切换到最后一张图的时候连续,把第一章照片复制到最后保证最后一张图切换到第一张图的时候连续。

<div class="carousel">
    <div class="pics-list">
      <img src="./img/img4.jpg">
      <img src="./img/img1.jpg">
      <img src="./img/img2.jpeg">
      <img src="./img/img3.jpg">
      <img src="./img/img4.jpg">
      <img src="./img/img1.jpg">
    </div>
    <div class="left"></div>
    <div class="right"></div>
  </div>

三、CSS样式

.carousel {
  position: relative;
  margin: 200px auto;
  width: 600px;
  height: 400px;
  background-color: pink;
  overflow: hidden;
}
.pics-list {
  display: flex;
  transition: all 0.3s ease;
  transform: translateX(-600px);
}
.pics-list img{
  width: 600px;
  height: 400px;
  object-fit: fill;
  flex-shrink: 0;
}
.left,
.right {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background-color: rgba(255, 255, 255, 0.7);
  opacity: 0;
  transition: all 0.3s ease;
}
.left:hover,
.right:hover {
  cursor: pointer;
}
.left {
  left: 10px;
}
.right {
  right: 10px;
}

四、JS逻辑

         这里有八个逻辑要处理,还是先抽出最本质的行为也就是图片切换来处理。一开始先处理功能比较简单的,后面就是按个人习惯想到要加什么就先加什么。

        1. 单纯的图片切换动作,接收图片序号

        2. 轮播逻辑函数和轮播开始(计时)

        3. 从最后一张图跳到第一张

                这里的逻辑是,图片移动轮播到图片序号为5的时候,也就是滑动到复制的第一张图的时候,结束transition的动画后要瞬移回真正的第一张,因此这里在每次transition结束后监听。

                监听事件的回调函数逻辑是:

                        (1)滑动到复制的第一张图后取消动画;
                        (2)瞬移回真正的第一张图
                        (3)在瞬移到真正的第一张图之后重新开始动画,所以要在下一次滑动动画进行之前把动画设置回来。

                        我感觉就是这里有点点绕需要多梳理几遍。

        4. 鼠标移入后停止自动轮播,左右按键显示

        5. 鼠标移除后重新开始自动轮播,左右按键不显示

        6. 右按键的逻辑

        7. 左按键的逻辑

        8. 从第一张图跳到最后一张图,同(3)

    let picIndex = 1
    const slideWidth = 600
    const frame = document.querySelector('.carousel')
    const picsList = document.querySelector('.pics-list')
    const leftBtn = document.querySelector('.left')
    const rightBtn = document.querySelector('.right')
    const picSwitch = function (index) {
      picsList.style.transform = `translateX(-${index * slideWidth}px)`
    }
    const autoSwitch = function () {
      picIndex ++
      if (picIndex > 5) {
        return
      }
      picSwitch(picIndex)
    }
    let autoTimer = setInterval(autoSwitch, 1000)
    picsList.addEventListener('transitionend', () => {
      if (picIndex === 5) {
        requestAnimationFrame(() => {
          picsList.style.transition = 'none'
          picIndex = 1
          picSwitch(picIndex)
          requestAnimationFrame(() => {
            picsList.style.transition = 'all 0.3s ease'
          })
        })
      }
    })
    frame.addEventListener('mouseenter', () => {
      clearInterval(autoTimer)
      leftBtn.style.opacity = 1
      rightBtn.style.opacity = 1
    })
    frame.addEventListener('mouseleave', () => {
      autoTimer = setInterval(autoSwitch, 2000)
      leftBtn.style.opacity = 0
      rightBtn.style.opacity = 0
    })
    rightBtn.addEventListener('click', () => {
      picIndex ++
      picSwitch(picIndex)
    })
    leftBtn.addEventListener('click', () => {
      picIndex --
      picSwitch(picIndex)
    })
    picsList.addEventListener('transitionend', () => {
        if (picIndex === 0) {
          requestAnimationFrame(() => {
            picsList.style.transition = 'none'
            picIndex = 4
            picSwitch(picIndex)
            requestAnimationFrame(() => {
              picsList.style.transition = 'all 0.3s ease'
            })
          })
        }
      })
  </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值