原生js实现轮播图的基本功能——淡进淡出

1、效果

2、需求

  • 轮播图自动切换;
  • 点击左右按钮切换上一张或下一张图片;
  • 指示器随轮播图自动切换,并允许点击切换到对应图片;
  • 使用CSS的transition属性实现淡进淡出效果;
  • 鼠标进入定时器暂停,鼠标离开则定时器开启;
  • 添加鼠标拖动可切换上/下一张;
  • 移动端时触摸屏幕左右滑动可切换上/下一张。

3、代码

html代码:

 <div class="carousel_box">
      <div class="carousel_box_inner">
        <div id="carousel">
          <div
            class="slide active"
            style="background-image: url('../assets/0001.jpeg')"
          ></div>
          <div
            class="slide"
            style="background-image: url('../assets/0002.jpeg')"
          ></div>
          <div
            class="slide"
            style="background-image: url('../assets/0003.jpg')"
          ></div>
          <div
            class="slide"
            style="background-image: url('../assets/0004.jpeg')"
          ></div>
        </div>
        <div class="btn_box">
          <button id="prev">Previous</button>
          <button id="next">Next</button>
        </div>
      </div>
      <!-- 指示器 -->
      <div class="carousel_dots">
        <span class="dots_item dot_active"></span>
        <span class="dots_item"></span>
        <span class="dots_item"></span>
        <span class="dots_item"></span>
      </div>
    </div>

cssd代码:

.carousel_box_inner {
        position: relative;
      }
      #carousel {
        width: 100%;
        height: 600px;
        overflow: hidden;
        margin: 0 auto;
      }

      .slide {
        width: 100%;
        height: 100%;
        background-size: cover;
        background-position: center;
        position: absolute;
        top: 0;
        left: 0;
        transition: opacity 0.5s;
        opacity: 0;
      }

      .active {
        opacity: 1;
      }

      .btn_box {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        color: white;
        border: none;
        cursor: pointer;
        width: 100%;
        display: flex;
        justify-content: space-between;
      }
      /* 指示灯 */
      .carousel_dots {
        margin: 0 auto;
        text-align: center;
      }

      .carousel_dots .dots_item {
        display: inline-block;
        width: 10px;
        height: 10px;
        background-color: #fff;
        border: 1px solid #000;
        border-radius: 50%;
        margin: 0 5px;
      }
      .carousel_dots .dots_item.dot_active {
        background-color: #000;
      }

js代码:

(function () {
        const slides = document.querySelectorAll(".slide");
        const dots = document.querySelectorAll(".dots_item");
        let currentIndex = 0;
        const interval = 3000; // 轮播间隔时间,单位为毫秒
        let isDragging = false;
        let startX = 0;

        // 下一张
        function updateCarousel() {
          // 移除当前活动的类
          slides[currentIndex].classList.remove("active");
          dots[currentIndex].classList.remove("dot_active");

          // 计算下一个索引
          currentIndex = (currentIndex + 1) % slides.length;

          // 添加活动类到新的当前项
          slides[currentIndex].classList.add("active");
          dots[currentIndex].classList.add("dot_active");
        }

        // 上一张
        function preSlide() {
          // 移除当前活动的类
          slides[currentIndex].classList.remove("active");
          dots[currentIndex].classList.remove("dot_active");

          // 计算上一个索引
          currentIndex = (currentIndex - 1 + slides.length) % slides.length;

          // 添加活动类到新的当前项
          slides[currentIndex].classList.add("active");
          dots[currentIndex].classList.add("dot_active");
        }

        // 启动自动轮播
        function startAutoSlide() {
          autoSlide = setInterval(updateCarousel, interval);
        }

        // 停止自动轮播
        function stopAutoSlide() {
          clearInterval(autoSlide);
        }
        // 定义自动轮播的定时器变量
        let autoSlide = setInterval(updateCarousel, interval);

        // 点击指示器切换图片
        dots.forEach(function (dot, index) {
          dot.addEventListener("click", function () {
            // 清除自动轮播
            clearInterval(autoSlide);

            // 移除当前活动的类
            slides[currentIndex].classList.remove("active");
            dots[currentIndex].classList.remove("dot_active");

            // 更新当前索引
            currentIndex = index;

            // 添加活动类到新的当前项
            slides[currentIndex].classList.add("active");
            dots[currentIndex].classList.add("dot_active");

            // 重新开始自动轮播
            autoSlide = setInterval(updateCarousel, interval);
          });
        });

        // 点击切换图片
        document.getElementById("next").addEventListener("click", function () {
          updateCarousel();
          // 重置自动轮播计时器
          clearInterval(autoSlide);
          autoSlide = setInterval(updateCarousel, interval);
        });

        document.getElementById("prev").addEventListener("click", function () {
          preSlide();

          // 重置自动轮播计时器
          clearInterval(autoSlide);
          autoSlide = setInterval(preSlide, interval);
        });

        // 鼠标进入轮播图区域
        document
          .getElementById("carousel")
          .addEventListener("mouseenter", stopAutoSlide);

        // 鼠标离开轮播图区域
        document
          .getElementById("carousel")
          .addEventListener("mouseleave", startAutoSlide);

        // 鼠标按下事件
        document
          .getElementById("carousel")
          .addEventListener("mousedown", function (e) {
            isDragging = true;
            startX = e.pageX;
          });

        // 鼠标移动事件
        document
          .getElementById("carousel")
          .addEventListener("mousemove", function (e) {
            if (isDragging) {
              let moveX = e.pageX - startX;
              if (Math.abs(moveX) > 50) {
                // 检查移动距离是否超过阈值
                if (moveX > 0) {
                  // 移动到下一张
                  updateCarousel();
                } else {
                  // 移动到上一张
                  preSlide();
                }
                isDragging = false;
              }
            }
          });

        // 鼠标释放事件
        document
          .getElementById("carousel")
          .addEventListener("mouseup", function (e) {
            isDragging = false;
          });

        // 鼠标离开轮播图区域时停止拖动
        document
          .getElementById("carousel")
          .addEventListener("mouseleave", function (e) {
            isDragging = false;
          });

        // 触摸开始事件
        document
          .getElementById("carousel")
          .addEventListener("touchstart", function (e) {
            stopAutoSlide(); // 触摸开始时停止自动轮播
            isDragging = true;
            startX = e.touches[0].pageX;
            
          });

        // 触摸移动事件
        document
          .getElementById("carousel")
          .addEventListener("touchmove", function (e) {
            let moveX = e.touches[0].pageX - startX;
            if (Math.abs(moveX) > 50) {
              // 检查移动距离是否超过阈值
              if (moveX > 0) {
                // 移动到下一张
                updateCarousel();
              } else {
                // 移动到上一张
                preSlide();
              }
              // 阻止默认行为,如滚动
              e.preventDefault();
            }
          });

        // 触摸结束事件
        document
          .getElementById("carousel")
          .addEventListener("touchend", function (e) {
            startAutoSlide(); // 触摸结束时重新启动自动轮播
            isDragging = false;
          });        
      })();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小奋斗♛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值