• 移动端 之 触摸事件、Tap事件和swipe事件


    触摸事件

    • touch是一个事件组,意思不止一个事件,是移动端滑动事件组,touchstart touchmove touchend touchcancel

    • touchstart 当刚刚触摸屏幕的时候触发

    • touchmove 在屏幕上来回的滑动的时候触发

    • touchend 离开屏幕的时候触发

    • touchcancel 被迫终止触摸的时候触发 (例如:来电 消息弹窗)

    <div class="box"></div>
    <script>
        var box = document.querySelector('.box');
        /*1 touchstart 当刚刚触摸屏幕的时候触发 */
        box.addEventListener('touchstart', function (e) {
            console.log('touchstart');
            console.log(e);
        });
        /*2 touchmove 在屏幕上来回的滑动的时候触发*/
        box.addEventListener('touchmove', function (e) {
            console.log('touchmove');
        });
        /*3 touchend 离开屏幕的时候触发*/
        box.addEventListener('touchend', function (e) {
            console.log('touchend');
            console.log(e);
        });
    
    
        /*获取触摸点坐标*/
        /*1. clientX/Y 记录的是基于视口的坐标*/
        /*2. pageX/Y 记录的是基于页面的坐标*/
        /*3. screenX/Y 记录的是基于屏幕的坐标*/
        /*不管什么坐标都可以  需要的是位置的改变 */
    </script>

    Tap事件

    在移动端使用click事件时,会存在大概200~300ms的延迟,如果不自己封装tap事件,那么就需要引入fastclick.js文件

    singleTap事件

    tap事件是依据touches组来封装的:

    自己封装的tap事件:

    var tap = function(dom,callback){
        //判断是否滑动过
        var isMove = false;
        //记录响应的速度
        var time = 0;
        dom.addEventListener('touchstart',function(e){
            time = Date.now();
            console.log(e);
        });
        dom.addEventListener('touchmove',function(e){
            isMove = true;
        });
        dom.addEventListener('touchend',function(e){
            var respondTime = Date.now() - time;
            /*tap*/
            if(!isMove && respondTime < 150){
                /*满足条件*/
                callback && callback();
            }
            //重置
            isMove = false;
        });
    }
    
    var box = document.querySelector('.box');
    
    tap(box, function(){
        // your code...
        console.log('tap触发了');
    });

    大神封装的tap事件

        HTMLElement.prototype.myTap = HTMLElement.prototype.myTap || function (callBack) {
          // myTapStart --- touchstart事件时间戳
          // myTapEnd --- 获取touchend事件时间戳
          // timeTap --- myTapStart - myTapEnd <= timeTap 时,被认为触发 tap 事件
          let myTapStart = 0,
            myTapEnd = 0,
            timeTap = 300;
          // 监听 touchstart 事件
          this.addEventListener('touchstart', function (e) {
            // 获取touchstart事件的时间戳
            myTapStart = e.timeStamp;
            // changedTouchs 是事件对象 TouchEvent 上面的属性,上面存储了一个当前操作的信息。
            let point = e.changedTouches[0];
            this.strX = point.pageX;
            this.strY = point.pageY;
            // 锁死 touchmove 事件
            this.isMove = false;
          }, false);
          // 监听 touchmove 事件
          this.addEventListener('touchmove', function (e) {
            let point = e.changedTouches[0];
            let changeX = point.pageX - this.strX;
            let changeY = point.pageY - this.strY;
            if (Math.abs(changeX) > 10 || Math.abs(changeY) > 10) {
              this.isMove = true;
            }
          }, false);
          // 监听 touchend 事件
          this.addEventListener('touchend', function (e) {
            // 获取 touchend 事件的时间戳
            myTapEnd = e.timeStamp;
            const isTimeTap = myTapEnd - myTapStart;
            if (!this.isMove && isTimeTap <= timeTap) {
              callBack();
            }
          }, false);
        };
    
    
        let box = document.querySelector(".box");
    
        box.myTap(function () {
          // your code...
          console.log("单击事件myTap");
        });

    doubleTap事件

    HTMLElement.prototype.doubleTap = HTMLElement.prototype.doubleTap || function (callBack) {
        // isTouchEnd
        // lastTime
        // lastTx lastTy --- 合理范围内的误差
        // firstTouchEnd --- 第一次 触发 touchend 事件
        // body --- iphone os
        // dTapTimer --- 定时器
        // startTx startTy --- 获取 touchstart 的位置
        // startTime --- 兼容 iphone os
        let isTouchEnd = false,
            lastTime = 0,
            lastTx = null,
            lastTy = null,
            firstTouchEnd = true,
            body = document.body,
            dTapTimer, startTx, startTy, startTime;
        // 监听 touchstart
        this.addEventListener('touchstart', function (e) {
            // 清除定时器s
            if (dTapTimer) {
                console.log('dTapTimer');
                clearTimeout(dTapTimer);
                dTapTimer = null;
            }
            // 获取 touchstart 的位置
            const touches = e.touches[0];
            startTx = touches.clientX;
            startTy = touches.clientY;
        }, false);
    
        // 监听 touchend
        this.addEventListener('touchend', function (e) {
            const touches = e.changedTouches[0],
                  endTx = touches.clientX,
                  endTy = touches.clientY,
                  now = Date.now(),
                  duration = now - lastTime;
    
            // 首先要确保能触发单次的 tap 事件
            if (Math.abs(startTx - endTx) < 6 && Math.abs(startTx - endTx) < 6) {
                console.log('单次点击的 touchstart 的位置和 touchend 的位置允许 6px 的误差');
                // 两次 tap 的间隔确保在 500 毫秒以内
                if (duration < 501) {
                    // 本次的 tap 位置和上一次的 tap 的位置允许一定范围内的误差
                    if (lastTx !== null && Math.abs(lastTx - endTx) < 45 && lastTy !== null && Math.abs(lastTy - endTy) < 45) {
                        firstTouchEnd = true;
                        lastTx = lastTy = null;
                        callBack()
                    }
                } else {
                    lastTx = endTx;
                    lastTy = endTy;
                }
            } else {
                firstTouchEnd = true;
                lastTx = lastTy = null;
            }
            // 获取上一次点击的时间戳
            lastTime = now;
        }, false);
    
        // 在 iOS 的 safari 上手指敲击屏幕的速度过快,
        // 有一定的几率会导致第二次不会响应 touchstart 和 touchend 事件
        // 同时手指长时间的touch不会触发click
    
        if (navigator.userAgent.toLowerCase().indexOf('iphone os')) {
            console.log('iphone os');
            body.addEventListener('touchstart', function (e) {
                startTime = Date.now();
            }, true);
    
            body.addEventListener('touchend', function (e) {
                let noLongTap = Date.now() - startTime < 501;
                if (firstTouchEnd) {
                    firstTouchEnd = false;
                    if (noLongTap && e.target === this) {
                        dTapTimer = setTimeout(function () {
                            // 永远不会执行setTimeout里面的代码,因为在 click 中清除了 dTapTimer
                            firstTouchEnd = true;
                            lastTx = lastTy = null;
                            console.log('fire double tap event at iphone os');
                            callBack()
                        }, 400);
                    }
                } else {
                    firstTouchEnd = true;
                }
            }, true);
    
            // iOS 上手指多次敲击屏幕时的速度过快不会触发 click 事件
            body.addEventListener('click', function (e) {
                if (dTapTimer) {
                    clearTimeout(dTapTimer);
                    dTapTimer = null;
                    firstTouchEnd = true;
                }
            }, false);
    
        }
    }
    let box = document.querySelector('.box')
    box.doubleTap(function() {
        console.log('doubleTap 触发了')
    })

    longTap事件

      <script>
        HTMLElement.prototype.longTap = HTMLElement.prototype.longTap || function (callBack) {
          let startTx, startTy, lTapTimer;
          this.addEventListener('touchstart', function (e) {
            // 清除定时器
            if (lTapTimer) {
              clearTimeout(lTapTimer);
              lTapTimer = null;
            }
            // 获取 touchstart 位置
            let touches = e.touches[0];
            startTx = touches.clientX;
            startTy = touches.clientY;
    
            lTapTimer = setTimeout(function () {
              callBack()
              console.log('fire long tap event');
            }, 1000);
    
            e.preventDefault();
          }, false);
    
          this.addEventListener('touchmove', function (e) {
            // 获取 touchmove 位置
            let touches = e.touches[0],
              endTx = touches.clientX,
              endTy = touches.clientY;
            // 定时器存在 并且 发生了 touchmove 清除定时器
            if (lTapTimer && (Math.abs(endTx - startTx) > 5 || Math.abs(endTy - startTy) > 5)) {
              clearTimeout(lTapTimer);
              lTapTimer = null;
            }
          }, false);
    
          this.addEventListener('touchend', function (e) {
            if (lTapTimer) {
              clearTimeout(lTapTimer);
              lTapTimer = null;
            }
          }, false);
    
        }
    
        let box = document.querySelector('.box')
        box.longTap(function() {
          // your code ...
          console.log('longTap 触发了')
        })

    swipe事件

      HTMLElement.prototype.swipe = HTMLElement.prototype.swipe || function (callBack) {
          let isTouchMove, startTx, startTy;
          this.addEventListener('touchstart', function (e) {
            let touches = e.touches[0];
    
            startTx = touches.clientX;
            startTy = touches.clientY;
            isTouchMove = false;
          }, false);
    
          this.addEventListener('touchmove', function (e) {
            isTouchMove = true;
            e.preventDefault();
          }, false);
    
          this.addEventListener('touchend', function (e) {
            if (!isTouchMove) {
              return;
            }
    
            let touches = e.changedTouches[0],
              endTx = touches.clientX,
              endTy = touches.clientY,
              distanceX = startTx - endTx
            distanceY = startTy - endTy,
              isSwipe = false;
    
            if (Math.abs(distanceX) >= Math.abs(distanceY)) {
              if (distanceX > 20) {
                callBack('left')
                console.log('fire swipe left event');
                isSwipe = true;
              } else if (distanceX < -20) {
                callBack('right')
                console.log('fire swipe right event');
                isSwipe = true;
              }
            } else {
              if (distanceY > 20) {
                callBack('up')
                console.log('fire swipe up event');
                isSwipe = true;
              } else if (distanceY < -20) {
                callBack('down')
                console.log('fire swipe down event');
                isSwipe = true;
              }
            }
    
            if (isSwipe) {
              console.log('fire swipe event');
            }
          }, false);
        }
    
        let box = document.querySelector('.box')
        box.swipe(function (direct) {
          // your code ...
          console.log('swipe 触发了' + direct)
        })
  • 相关阅读:
    Java爬取丁香医生疫情数据并存储至数据库
    mysql 获取昨天日期、今天日期、明天日期以及前一个小时和后一个小时的时间
    java.lang.UnsatisfiedLinkError: /usr/openv/java/jre/lib/amd64/libawt_xawt.so: libXtst.so.6: cannot open shared object file: No such file or directory
    Linux下打包压缩war、解压war包和jar命令
    Linux常用基本命令大全
    Git在eclipse中的配置
    CentOS 7 安装Rabbitmq
    Jmeter测试普通java类说明
    单例模式的7中写法
    Hyperledger Fabric 1.0 学习搭建 (五)--- 启动Fabric多节点集群
  • 原文地址:https://www.cnblogs.com/houfee/p/10413687.html
Copyright © 2020-2023  润新知