关于javascript:尝试检测移动端click延时

据说挪动端click有个延时300ms响应的机制,目标是为了辨别单击、双击。如果300ms内再次点击,则断定为双击,挪动端的双击用于缩放页面;否则为单击,执行click的事件处理函数。
勾销click延时响应的两种做法:

  1. 设置视口标签,禁用缩放页面性能,浏览器也会相应勾销对双击的响应。
  2. 利用touch系列事件包装一组监听器,只有touch持续时间小于某个值才归为点击(大于就是长按或者拖拽了),进而执行事件处理函数。

按理说,当初挪动端都会设置viewport:

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

所以,第2种做法有点脱裤子放屁的感觉?
好奇到底提早多久,真的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延时了。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理