原生js实现移动端轮播图滑动切换

移动端手势
轮播图分析
  1. 自动轮播且无缝 [定时器、过渡动画]
  2. 分页器要随着图片的轮播而改变 [根据索引切换]
  3. 滑动效果 [touch事件]
  4. 图片随着分页器变化
  5. 滑动结束的时候,如果滑动的距离不超过屏幕的1/3,就恢复回去 [过渡]
  6. 滑动结束的时候,如果滑动的距离超过屏幕的1/3,就切换 [滑动方向 + 过渡]]
html页面结构
   <!--轮播图-->
        <div class="jd_banner">
            <ul class="clearfix">
                <li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l2.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l3.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l4.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l5.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l6.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l7.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
            </ul>
            <ul class="clearfix">
                <li class="now"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
        </div>
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插件最好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值