使用JavaScript怎么实现一个移动端的轮播图效果
创始人
2024-12-26 20:42:52
0次

移动端手势

轮播图分析

1、自动轮播且无缝 [定时器、过渡动画]
2、分页器要随着图片的轮播而改变 [根据索引切换]
3、滑动效果 [touch事件]
4、图片随着分页器变化
5、滑动结束的时候,如果滑动的距离不超过屏幕的1/3,就恢复回去 [过渡]
6、滑动结束的时候,如果滑动的距离超过屏幕的1/3,就切换 [滑动方向 + 过渡]]

html页面结构


  
   
    
  •     
  •     
  •     
  •     
  •     
  •     
  •     
  •     
  •     
  •                  
  •     
  •     
  •     
  •     
  •     
  •     
  •    

    js部分

    /* 动态设置过渡 */
    var addTransition = function (ele) {
     ele.style.transition = "all .6s";
     ele.style.webkitTransition = "all .6s";
    };
    /* 移除过渡效果 */
    var removeTransition = function (ele) {
     ele.style.transition = "none";
     ele.style.webkitTransition = "none";
    };
    /* 设置容器平移 -- 也就是滑动动画 
     ele:当前元素
     xwidth:平移的距离
    */
    var setTranslateX = function (ele, xwidth) {
     ele.style.transform = "translateX(" + xwidth + "px)";
     ele.style.webkitTransform = "translateX(" + xwidth + "px)";
    }
    var banner = function () {
     /** 轮播图分析 */
     /** 1 自动轮播且无缝 [定时器、过渡动画]
      * 2 点要随着图片的轮播而改变 [根据索引切换]
      * 3 滑动效果 [touch事件]
      * 4 图片随着点而变化
      * 5 滑动结束的时候,如果滑动的距离不超过屏幕的1/3,就恢复回去 [过渡]
      * 6 滑动结束的时候,如果滑动的距离超过屏幕的1/3,就切换 [滑动方向 + 过渡]]
      */
     var timer = ''
     /* 封装定时器函数 */
     var startInterval = function () {
      timer = setInterval(function () {
       index++;// 基于索引 做位移
       addTransition(imgBox); // 为轮播图片组的ul设置过渡函数
       setTranslateX(imgBox, -index * width);// 根据当前索引值计算平移的距离
      }, 2000);
     }
     var banner = document.querySelector(".jd_banner");
     var width = banner.offsetWidth; // 屏幕的宽度
     var imgBox = banner.querySelector("ul:first-child"); // 轮播图片ul
     var length = imgBox.querySelectorAll("li").length; // 图片的个数
     var pointBox = banner.querySelector("ul:last-child");// 分页器ul
     var points = pointBox.querySelectorAll("li");// 分页器集合
    
     var index = 1; // 初始化索引,由于要无缝衔接,索引从1开始
     startInterval();
     
     /* transitionend事件:当元素过渡动画结束后执行
     每次轮播动画结束后,判断当前索引值
     */
     imgBox.addEventListener("transitionend", function () {
      if (index >= length - 1) {
       index = 1;
       // 清过渡,瞬间定位imgBox 
       removeTransition(imgBox);
       setTranslateX(imgBox, -index * width);
      }
      // 滑动的时候也需要无缝
      else if (index <= 0) {
       index = 8;
       removeTransition(imgBox);
       setTranslateX(imgBox, -index * width);
      }
      showPoint(index - 1); // 改变分页器状态
     });
    
     var showPoint = function (index) {
      for (var i = 0; i < points.length; i++) {
       points[i].className = '';
      }
      points[index].className = "now";
     };
     /* 滑动切换 (touch事件) */
     var startX = 0; // 触摸起始点
     imgBox.addEventListener("touchstart", function (e) {
      // 记录起始位置的X坐标
      clearInterval(timer);
      startX = e.touches[0].clientX;
     });
     var distanceX = 0;
     var translateX = 0;
     // **** 加一个标识,判断用户有没有滑动
     var isMove = false
     imgBox.addEventListener("touchmove", function (e) {
      var moveX = e.touches[0].clientX;
      // 计算位移,有正负方向
      distanceX = moveX - startX;
      // 计算目标元素的位移
      // 元素将要的定位 = 当前定位 + 手指移动的距离
      translateX = -index * width + distanceX;
      // ********** 要想图片实时地跟着手指走,一定要把过渡清楚掉
      removeTransition(imgBox)
      setTranslateX(imgBox, translateX);
      isMove = true;// 确定用户有滑动
      e.preventDefault(); // 去除移动端浏览器默认的滑动事件
     });
    
     imgBox.addEventListener("touchend", function (e) {
      if (isMove) {
       if (Math.abs(distanceX) > width / 3) {
        // 切换
        if (distanceX > 0) {
         // 上一张
         index = index - 1;
        } else {
         // 下一张
         index = index + 1;
        }
        addTransition(imgBox); // 设置过渡动画
        setTranslateX(imgBox, -index * width);
        if (index >= 9) {
         index = 1;
        }
        if (index <= 0) {
         index = 8;
        }
        showPoint(index - 1);
    
       } else {
        // 不满足滑动条件,回退到之前的状态
        addTransition(imgBox);
        setTranslateX(imgBox, -index * width);
        showPoint(index - 1);
       }
      }
      // **** 最好做一次参数的重置
      startX = 0;
      distanceX = 0;
      isMove = false;
      // ****** 为了严谨,再清一次定时器
      clearInterval(timer)
      // 加上定时器
      startInterval();
     });
    };

    总结

    原生js实现滑动切换的原理主要还是利用移动端的手势事件

    • touchstart 当手指触摸屏幕时触发

    • touchmove 当手指在屏幕中滑动的时候触发

    • touchend 当手指离开屏幕时触发

    利用touch相关事件实现移动端常见滑动效果和移动端常见的手势事件。

    而swiper插件的底层实现原理也是这个,因此,为了快速开发,还是使用swiper插件最好

    相关内容

    热门资讯

    空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
    空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
    格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
    空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
    格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
    品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
    空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
    空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
    中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
    中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...