移动端点击延迟问题研究

测试

html

<button id="btn">click me, touch me or kiss me</button>

javascript

// 通过是否调用 fastclick 这个库来屏蔽点击延迟来查看是否存在点击延迟的问题
// FastClick.attach(document.body);

var touchEndTime;
var clickTime;
var clickDelay;

function now() {
    return new Date().getTime();
}

$('#btn').on('click', function() {
    clickTime = now();
    clickDelay = clickTime - touchEndTime;
    alert(clickDelay);
});

$('#btn').on('touchEnd', function() {
    touchEndTime = now();
});
这个页面包含 meta 标签:
<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

测试结果

测试环境:iPhone6s微信内置浏览器
未使用 fastclick:测试结果延迟在 350 ~ 370 之间

使用 fastclick: 测试结果在 0 ~ 5 之间

测试环境:iPhone6s贝贝客户端v4.9.05

未使用 fastclick: 测试结果在 5 ~ 20 之间

使用 fastclick:测试结果在 0 ~ 5 之间

什么是点击延迟

现在我们来看看什么是点击延迟?点击延迟是指移动端浏览器在 touchend 和 click 之间存在 300ms ~ 350ms 的延迟。为了判断用户是否是进行双击操作。因为移动端双击是放大文字的手势操作。

解决方案

  1. 对于chrome和firefox,可以通过禁用伸缩,即在 head 上的 meta 标签添加 user-scalable = no。如下:

    <meta name="viewport" content="width=device-width, user-scalable=no">
  2. chrome32+ 可以将 viewport 的宽度设置成 device-width.

  3. IE10+,可以使用 pointerEvents。可以让特定的元素或者整个文档中的元素移除点击延迟的问题,同时不会影响 pinch-zooming

    a, button, .myelements
    {
    -ms-touch-action: manipulation;    /* IE10  */
    touch-action: manipulation;        /* IE11+ */
    }
  4. 通过 touchend 事件代替 click 事件。

  5. 使用 zepto.js 的 tap 事件,通过 singleTap 和 doubleTap 来区分单击和双击。但是会出现点击穿透,而且对于已经使用 click 的文件,改动成本太大。

  6. 终极大 boss。 fastclick。上面的几种方法都是针对某些浏览器,或者某些浏览器的某些版本,或者会影响到我们平常使用方式的解决方案。使用起来不方便且考虑的细节很多,实践难度比较大。fastclick 作为一个终极的解决方案,使用方便,文件大小压缩后只有 3.3k。对于交互相对复杂的移动端web页面或应用是一个相对不错的解决方案。

    javascript:
    if ('addEventListener' in document) {
        document.addEventListener('DOMContentLoaded', function() {
            FastClick.attach(document.body);
        }, false);
    }
    jQuery:
    $(function() {
        FastClick.attach(document.body);
    });
    CommonJS:
    var attachFastClick = require('fastclick');
    attachFastClick(document.body);
    AMD:
    var FastClick = require('fastclick');
    FastClick.attach(document.body, options);

参考:

  1. 5-ways-prevent-300ms-click-delay-mobile-devices

  2. pointerevents


wangfulin
6.1k 声望107 粉丝