動態

詳情 返回 返回

嘗試檢測移動端click延時 - 動態 詳情

據説移動端click有個延時300ms響應的機制,目的是為了區分單擊、雙擊。如果300ms內再次點擊,則判定為雙擊,移動端的雙擊用於縮放頁面;否則為單擊,執行click的事件處理函數。
取消click延時響應的3種做法:

  1. 設置視口標籤,禁用縮放頁面功能,瀏覽器也會相應取消對雙擊的響應。
  2. 利用touch系列事件包裝一組監聽器,只有touch持續時間小於某個值才歸為點擊(大於就是長按或者拖拽了),進而執行事件處理函數。
  3. 使用fastClick插件。

按理説,現在移動端都會設置viewport:

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, min-scale=1.0, max-scale=1.0">

所以,第2種做法有點脱褲子放屁的感覺?第3種也過時了吧?
我好奇究竟延遲多久,真的300ms?於是寫了第2種做法的監聽函數setFastClick,並檢測了實際延時,代碼如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, min-scale=1.0, max-scale=1.0"> -->
    <!-- <meta name="viewport" content="width=device-width"> -->
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }

        p {
            width: 200px;
            height: 200px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div>click me and console.log('fast click')</div>
    <p>click me and console.log('normal, slow and delay click')</p>
    <script>
        function setFastClick(obj, callback) {
            var isMove = false;
            var startTime = 0;
            obj.addEventListener('touchstart', function () {
                startTime = Date.now();
            });
            obj.addEventListener('touchmove', function () {
                isMove = true;
            });
            obj.addEventListener('touchend', function () {
                // 觸摸開始至結束小於150ms算點擊;高於150ms、滑動等等可能歸為長按、拖動
                if (isMove == false && Date.now() - startTime < 150) {
                    callback && callback();
                }
                isMove = false;
                startTime = 0;
            });
        }

        var div = document.querySelector('div');
        var divStart = 0;
        div.addEventListener('touchstart', function () {
            divStart = Date.now();
        });
        setFastClick(div, function () {
            console.log('fast click, react time:' + (Date.now() - divStart));
            divStart = 0;
        });

        var p = document.querySelector('p');
        var pStart = 0;
        p.addEventListener('touchstart', function () {
            pStart = Date.now();
        });
        p.addEventListener('click', function () {
            console.log('normal, slow and delay click, react time:' + (Date.now() - pStart));
            pStart = 0;
        });

    </script>
</body>

</html>

設置視口標籤禁用縮放後,瀏覽器就直接取消click延時機制了。所以,這裏要把viewport註釋掉。
然而,一開始我以為刪掉initial-scale=1.0就行了,結果愣是沒出現延時,響應時間都是幾十毫秒。後來一狠心把viewport整行去掉,才發現了確實延時了300ms。
想想也是,width=device-width意思就是頁面寬度等於設備寬度,就是告訴瀏覽器不必縮放了,瀏覽器也就取消click延時了。

user avatar dingtongya 頭像 grewer 頭像 linlinma 頭像 zourongle 頭像 linx 頭像 u_17443142 頭像 yqyx36 頭像 assassin 頭像 nznznz 頭像 yangxiansheng_5a1b9b93a3a44 頭像 DolphinScheduler 頭像 user_ze46ouik 頭像
點贊 79 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.