移动端click延迟和tap事件

一、click等事件在移动端的延迟

click事件在移动端和pc端均可以触发,但是在移动端有延迟现象。

1、背景

由于早期移动设备浏览网页时内容较小,为了增强用户体验,苹果公司专门为移动设备设计了双击放大的功能,以确保用户可以方便地放大网页内容,但是当用户单击按钮的时候,移动设备需要延迟约300ms执行,以判断用户是否是要双击。

2、验证

下面通过js代码来直观地验证click等事件的延迟

<div class="result">点我试试</div>

var startTime;
        //打印信息函数
        var log = function(msg) {
            var p = document.createElement('p');
            //计算触发事件
            //new Date().getTime()  获取当前时间
            //new Date().getTime()-startTime  获取事件响应与touchStart的时间差
            p.innerHTML = (new Date().getTime())+" : "+(new Date().getTime()-startTime)+" : "+msg;
            //添加到页面中中
            document.body.appendChild(p);
        }
        //触屏
        var touchStart = function(){
            startTime = new Date().getTime();
            log('touchStart');
        }
        //触屏结束
        var touchEnd = function() {
            log('touchEnd');
        }
        //鼠标按下
        var mouseDown = function() {
            log('mouseDown');
        }
        //鼠标点击
        var mouseClick = function(){
            log('mouseClick');
        }
        //鼠标弹起
        var mouseUp = function() {
            log('mouseUp');
        }
    var result = document.querySelector('.result');
    //绑定事件
    result.addEventListener('mousedown',mouseDown);   //先绑定pc端点击事件
    result.addEventListener('click',mouseClick);
    result.addEventListener('mouseup',mouseUp);
    result.addEventListener('touchstart',touchStart);//绑定移动端事件
    result.addEventListener('touchend',touchEnd);   

移动端 时间响应原则:优先响应移动端独有事件。

二、解决办法

1、使用touch事件模拟click事件

如下使用touchstart和touched封装了一个移动端的tap事件

var idcast = {
        //传入dom元素
        tap:function(dom,callback) {
            //判断是否传入了dom元素,或者dom元素是否是一个对象
            if(!dom||typeof dom != "object"){
                return;
            }
            var startX,startY,time,moveX,moveY,distanceX,distanceY;
            dom.addEventListener("touchstart",function(e) {
                if(e.targetTouches.length>1) {
                    return;
                }
                startX = e.targetTouches[0].clientX;
                startY = e.targetTouches[0].clientY;
                time = Date.now();
            });
            dom.addEventListener("touchend",function(e) {
                if(e.changedTouches.length>1) {//说明不止一个手指
                    return;
                }
                //判断时间差异
                if(Date.now()-time>150){//长按操作
                    return;
                }
                //获取松开手指的时候的坐标与触摸开始时的坐标差异
                moveX = e.changedTouches[0].clientX;
                moveY = e.changedTouches[0].clientY;
                distanceX = moveX - startX;
                distanceY = moveY - startY;
                //判断坐标差异
                if(Math.abs(distanceX) < 6 && Math.abs(distanceY) <6) {//说明是点击而非滑动
                    //执行tap事件相应之后的处理操作
                    //若函数不为空才调用
                    callback&&callback(e);
                    console.log("移动端点击单击事件--tap事件");
                }
            })
        }
    }

可以直接调用idcast中tap方法。

2、使用zepto中已经封装好的tap事件直接调用

$(menuBox).on("tap",callback)

zepto下载链接:https://github.com/madrobby/zepto

posted @ 2018-12-25 19:09  阿豪的girl  阅读(1910)  评论(2编辑  收藏  举报