关于移动端浏览器click事件延迟触发的研究

click事件延迟触发原因

  为了优化PC站页面在移动设备上的显示,现代移动端浏览器默认开启页面双击缩放功能。为了判断用户当前手势是单击还是双击,浏览器在touchend事件触发后设置了一个300ms左右的延时。如果在该延时内用户再次触摸屏幕,则浏览器判定当前用户手势是双击,否则为单击并且触发click事件。因此,移动端浏览器click事件延迟触发的根本原因在于浏览器支持页面双击缩放。
  在Chrome 65、Firefox 10.6和Safari(iOS 11.2)上验证click事件的延迟触发,测试结果依次展示如下:

Chrome 65测试结果
Firefox 10.6测试结果
Safari(iOS 11.2)测试结果

解决click事件延迟触发的方案

  移动端浏览器click事件的延迟触发会损害用户体验,针对延迟产生的原因,目前主要有以下解决方案:
  (1)禁止页面缩放。在页面html文档的head标签中插入如下meta标签会禁止页面的缩放功能。浏览器检测到页面缩放功能被禁止之后会消除click事件的300ms延时,实现快速点击。

1
2
3
<!--以下标签任选其一-->
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,minimum-scale=1,maximum-scale=1">

  在Chrome 65、Firefox 10.6和Safari(iOS 11.2)上验证该方案的可行性,测试结果依次展示如下:

Chrome 65测试结果
Firefox 10.6测试结果
Safari(iOS 11.2)测试结果

  根据测试结果可以看出,该方案只在Chrome和Firefox中生效,在Safari中不起作用。测试发现,在Chrome和Firefox中使用该方案时,网页不能被缩放(包括双击缩放和双指缩放),但是在Safari浏览器中,网页仍然可以被缩放(包括双击缩放和双指缩放)。

  (2)设置浏览器视口宽度等于设备屏幕宽度。该方法的原理在于当浏览器检测到页面设置的视口宽度小于或者等于设备宽度时,就会认为该页面已经针对移动端设备进行优化了页面,不需要双击缩放功能来保证页面在移动设备上的合理展示,因此,浏览器会禁用页面的双击缩放功能。此时,click事件延时触发的问题也自然被消除。在页面html文档的head标签中插入如下meta标签可以设置浏览器视口等于设备宽度。

1
<meta name="viewport" content="width=device-width">

  在Chrome 65、Firefox 10.6和Safari(iOS 11.2)上验证该方案的可行性,测试结果依次展示如下:

Chrome 65测试结果
Firefox 10.6测试结果
Safari(iOS 11.2)测试结果

  根据测试结果可以看出,该方法在Chrome、Firefox和Safari上均可以消除click事件延迟300s触发的问题。该方法禁止了页面的双击缩放功能,保留了页面的双指缩放功能。测试发现,一旦用户使用了页面的双指缩放功能,在页面处于放大的状态下,浏览器的click事件触发会再次具有300ms延迟,当页面恢复至初始状态后,浏览器click事件触发延迟会消除。

  (3)使用CSS属性touch-action。通过给页面所有元素或者特定的元素设置touch-action属性可以保证点击对应的元素时,click事件响应无延时。设置方法如下:

1
2
3
[selector] {
touch-action: manipulation;
}

  在Chrome 65、Firefox 10.6和Safari(iOS 11.2)上验证该方案的可行性,测试结果依次展示如下:

Chrome 65测试结果
Firefox 10.6测试结果
Safari(iOS 11.2)测试结果

  根据测试结果可以看出,在Chrome、Firefox和Safari浏览器上使用该方法均可以消除click事件的触发延迟。从caniuse查询可知,Chrome 36+、Firefox 52+完全支持该属性,Safari 9.3+支持该属性的部分功能。

  (4)使用touchend事件替换click事件。

  (5)使用FT Labs开发的开源库fastclick

总结

  移动端浏览器的click事件触发具有300ms的延迟是浏览器为了支持页面的双击缩放而引入的一个特性。为了消除这一特性给用户体验带来的不好影响,可以根据项目实际情况对上述五种方案进行选择,确定最合适的方案。

参考文献

  1. https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away
  2. https://www.sitepoint.com/5-ways-prevent-300ms-click-delay-mobile-devices/
  3. https://developer.telerik.com/featured/300-ms-click-delay-iOS-8/
  4. https://codereview.chromium.org/18850005/#ps106001
  5. http://baishusama.github.io/2017/03/27/%E7%A7%BB%E5%8A%A8%E7%AB%AF-click-%E4%BA%8B%E4%BB%B6%E7%9A%84-300ms-%E5%BB%B6%E8%BF%9F/