移動端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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM