封装移动端手势事件

整体思路,以及代码实现,每一步进行分析,完善,通过移动端的三大事件进行封装,我会将思路写在代码中,这样方便理解!!

开始: action!!!

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>大玄!!</title>
    </head>
    
    <body>
        <script>
            function swipe(ele, options) {
    
    
                // 1.首先将元素绑定 触摸开始事件,并将事件对象传入
                ele.addEventlistener('touchstart', function(e) {
    
                });
    
                // 2.将元素绑定 触摸移动事件, 并将事件对象传入
                ele.addEventistener('touchmove', function(e) {
    
                });
    
                // 3.将元素绑定 触摸结束事件,并将事件对象传入
                ele.addEventlistener('touchend', function() {
    
                });
    
            };
    
            var html = document.documentElement;
        </script>
    </body>
    
    </html>

不要着急,先将整体思路理一下,通过三大事件进行模拟swipe事件,然后对每一步进行完善!!!


第二步

        <title>大玄!!</title>
    </head>
    
    <body>
        <script>
            function swipt(ele, options) {
                // 5.定义全局变量
                var startX;
                var startY;
                var moveX;
                var moveY;
                // 7.1
                var isMove = false;
    
                // 1.首先将元素绑定 触摸开始事件,并将事件对象传入
                ele.addEventlistener('touchstart', function(e) {
                    // 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
                    startX = e.touches[0].pageX;
                    startY = e.touches[0].pageY;
                });
    
                // 2.将元素绑定 触摸移动事件, 并将事件对象传入
                ele.addEventistener('touchmove', function(e) {
                    // 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
                    // 接着定义全局变量
                    moveX = e.touches[0].pageX;
                    moveY = e.touches[0].pageY;
                    // 7.2 如果用户划拉了,将开关重新赋值,
                    isMove = true;
                });
    
                // 3.将元素绑定 触摸结束事件,并将事件对象传入
                ele.addEventlistener('touchend', function() {
                    // 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
                    if (isMove) {
                        // 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
                        // 8.1 取绝对值
                        var absX = Math.abs(moveX - startX);
                        var absY = Math.abs(moveY - startY);
                        // 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
                        if (absX > absY) {
                            console.log('水平方向滑动');
                        } else {
                            console.log('垂直方向滑动');
                        }
                    }
                });
            };
    
            var html = document.documentElement;
    
            swipe(html, {
                swipeLeft: function() {
                    alert('向左滑动')
                },
                swipeRight: function() {
                    alert('向右滑动')
                }
            });
        </script>
    </body>
好了,大概这个样子就可以了,但是你还会发现一个问题,就是这些方法,是不是用户全部都得传入才可以啊,如果不传的话,就要报错了,所以这里面就会用到默认值,在函数里面咱们进行定义,如果没有传入的话,就使用默认值,要是穿入了的话,就使用用户传入的值.
        <title>大玄!!</title>
    </head>
    
    <body>
        <script>
            function swipt(ele, options) {
                // 5.定义全局变量
                var startX;
                var startY;
                var moveX;
                var moveY;
                // 7.1
                var isMove = false;
    
                // 1.首先将元素绑定 触摸开始事件,并将事件对象传入
                ele.addEventlistener('touchstart', function(e) {
                    // 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
                    startX = e.touches[0].pageX;
                    startY = e.touches[0].pageY;
                });
    
                // 2.将元素绑定 触摸移动事件, 并将事件对象传入
                ele.addEventistener('touchmove', function(e) {
                    // 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
                    // 接着定义全局变量
                    moveX = e.touches[0].pageX;
                    moveY = e.touches[0].pageY;
                    // 7.2 如果用户划拉了,将开关重新赋值,
                    isMove = true;
                });
    
                // 3.将元素绑定 触摸结束事件,并将事件对象传入
                ele.addEventlistener('touchend', function() {
                    // 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
                    if (isMove) {
                        // 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
                        // 8.1 取绝对值
                        var absX = Math.abs(moveX - startX);
                        var absY = Math.abs(moveY - startY);
                        // 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
                        if (absX > absY) {
                            // console.log('水平方向滑动');
                            // 10.由于一个周是两个方向,so 有正向与反向两种说法,接下来进一步进行判断
                            // 如果移动的距离大于起始距离的话,那就是向右划拉,如果小于的话就是向左划拉
                            if (moveX - startX > 0) {
                                // console.log('这是向右滑动');
                                options.swipeRight();
                            } else {
                                // console.log('这是向左滑动');
                                options.swipeLeft();
                            }
                        } else { //  这里判断完了,咱们要的结果不是打印什么,而是要执行什么方法,所以采用对象的方式进行传值
                            // console.log('垂直方向滑动');
                            if (moveY - startY > 0) {
                                // console.log('这是向下滑动');
                                options.swipeDown();
                            } else {
                                // console.log('这是向上滑动');
                                options.swipeUp();
                            }
                        }
                    }
                    // 在结束的时候,不管触发没有,都要将开关重新赋值回去
     				isMove = false;
                });
            };
            var html = document.documentElement;
    
            swipe(html, {
                swipeLeft: function() {
                    alert('向左滑动')
                },
                swipeRight: function() {
                    alert('向右滑动')
                },
                swipeUp: function() {
                    alert('向上滑动');
                },
                swipeDown: function() {
                    {
                        alert('向下滑动');
                    }
                }
            });
        </script>

将函数进行优化,封装的更好一丢丢

下面的代码将是优化完成之后的样子,虽然不能实现什么大的功能,但是基本的移动端的滑动事件可以实现了!!
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>大玄!!</title>
    </head>
    
    <body>
        <script>
            function swipe(ele, options) {
                // 5.定义全局变量
                var startX;
                var startY;
                var moveX;
                var moveY;
                var disX;
                var disY;
                // 7.1
                var isMove = false;
    
                // 12.设置默认值
                var defaults = {
                    swipeRight: function() {},
                    swipeLeft: function() {},
                    swipeDown: function() {},
                    swipeUp: function() {},
                    drag: function() {}
                }
    
                // 13.不传的话,就要报错了,所以这里面就会用到默认值,在函数里面咱们进行定义,如果没有传入的话,就使用默认值,要是穿入了的话,就使用用户传入的值.
                // for (var k in defaults) {
                //     defaults[k] = options[k];
                // };
    
                // 上面是一种方法,这里介绍另一种方法对象覆盖的方法
                Object.assign(defaults, options);
    
    
                // 1.首先将元素绑定 触摸开始事件,并将事件对象传入
                ele.addEventListener('touchstart', function(e) {
                    // 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
                    startX = e.touches[0].pageX;
                    startY = e.touches[0].pageY;
    
                    disX = startX - ele.offsetLeft;
                    disY = startY - ele.offsetTop;
                });
    
                // 2.将元素绑定 触摸移动事件, 并将事件对象传入
                ele.addEventListener('touchmove', function(e) {
                    // 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
                    // 接着定义全局变量
                    moveX = e.touches[0].pageX;
                    moveY = e.touches[0].pageY;
                    // 7.2 如果用户划拉了,将开关重新赋值,
                    isMove = true;
    
                    e.info = {
                        startX: startX,
                        startY: startY,
                        disX: disX,
                        disY: disY
                    };
    
                    // 13.将在touchmove事件发生的时候要做的事情写在函数外面 => drag
                    defaults.drag.call(ele, e);
                });
    
                // 3.将元素绑定 触摸结束事件,并将事件对象传入
                ele.addEventListener('touchend', function() {
                    // 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
                    if (isMove) {
                        // 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
                        // 8.1 取绝对值
                        var absX = Math.abs(moveX - startX);
                        var absY = Math.abs(moveY - startY);
                        // 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
                        if (absX > absY) {
                            // console.log('水平方向滑动');
                            // 10.由于一个周是两个方向,so 有正向与反向两种说法,接下来进一步进行判断
                            // 如果移动的距离大于起始距离的话,那就是向右划拉,如果小于的话就是向左划拉
                            if (moveX - startX > 0) {
                                // console.log('这是向右滑动');
                                options.swipeRight();
                            } else {
                                // console.log('这是向左滑动');
                                options.swipeLeft();
                            }
                        } else { //  这里判断完了,咱们要的结果不是打印什么,而是要执行什么方法,所以采用对象的方式进行传值
                            // console.log('垂直方向滑动');
                            if (moveY - startY > 0) {
                                // console.log('这是向下滑动');
                                options.swipeDown();
                            } else {
                                // console.log('这是向上滑动');
                                options.swipeUp();
                            }
                        }
                    }
                    // 11.在结束的时候,不管触发没有,都要将开关重新赋值回去
                    isMove = false;
                });
            };
    
            var html = document.documentElement;
    
            swipe(html, {
                swipeLeft: function() {
                    console.log('向左滑动')
                },
                swipeRight: function() {
                    console.log('向右滑动')
                },
                swipeUp: function() {
                    console.log('向上滑动');
                },
                swipeDown: function() {
                    console.log('向下滑动');
                },
                drag: function(e) {
                    console.log('拖拽事件');
                    // 在拖拽的时候需要获取到移动过程中的 pageX与pageY,由于在外面是获取不到函数内部的属性,所以在函数内部进行对象输出
                    console.log('开始的X距离是' + e.info.startX);
                    console.log('开始的Y距离是' + e.info.startY);
                    console.log('盒子内部的X距离是' + e.info.disX);
                    console.log('盒子内部的Y距离是' + e.info.disY);
                    a = e.touches[0].pageX - e.info.disX + 'px';
                    b = e.touches[0].pageY - e.info.disY + 'px';
                    console.log(a);
                    console.log(b);
    
                }
            });
        </script>
    </body>
    
    </html>

在此附上我的QQ: 2489757828 有问题的话可以一同探讨
我的私人博客: 李大玄

猜你喜欢

转载自blog.csdn.net/weixin_43553701/article/details/93386468