正文
解决方案
以下可以通过 hack 技巧,不添加 fastClick 也能修复延迟的问题
禁用缩放
-
Chrome on Android (all versions)
-
iOS 9.3
<meta name="viewport" content="user-scalable=no" />
复制代码
或者
html {
touch-action: manipulation;
}
复制代码
html {
touch-action: manipulation; // IE11+
-ms-touch-action: manipulation; // IE10
}
复制代码
不禁用缩放
-
Chrome 32+ on Android
-
iOS 9.3
<meta name="viewport" content="width=device-width" />
复制代码
经测试,如果不添加
width=device-width
不管是 Android 还是 iOS 在已修复的版本中仍然会出现延时的问题。
WebView
上面说了这么多,都是针对移动端浏览器的,既然是提到移动端,WebView 当然不得不说啦。
Android WebView
如何设计一个优雅健壮的 Android WebView?
Android WebView 中 300ms 的延迟问题和移动端浏览器解决思路一致。
iOS WebView
UIWebView
In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView. Additionally, consider setting the WKPreferences property javaScriptEnabled to false if you render files that are not supposed to run JavaScript.
iOS WebView 就有点让人头疼了。因为 iOS 8 之前一直都是 UIWebView,iOS 8 出了个新秀 WKWebView,那么 iOS 9.3 300ms 延迟的 BUG 修复到底干了啥呢?在客户端 iOS 小姐姐的帮助下,最终的测试结果是 UIWebView 300ms 延迟的问题到现在一直存在,哪怕是最新的 iOS 版本(这大概这就是为什么老外推荐使用 WKWebView 而非 UIWebView,估计是不想修 BUG 了吧 😂),但是 WKWebView 在 iOS 9.3 的时候将这个问题给修复了。也就是说 iOS 9.3 之前 WKWebView 仍然是存在 300ms 延迟的问题的(忙活了半天,总算把所有的都给理清楚了 🙄)。
FastClick 原理解析
这部分可能有点烂大街了,网上一搜一大把,再说也没啥意思,我就挑点个人觉得有意思的说一下 😁。
原理
首先,讲一下 fastClick 的实现原理吧,MDN 上
同时支持触屏事件和鼠标事件
也有提到。
移动端,当用户点击屏幕时,会依次触发
touchstart
,
touchmove
(0 次或多次),
touchend
,
mousemove
,
mousedown
,
mouseup
,
click
。
touchmove
。只有当手指在屏幕发生移动的时候才会触发
touchmove
事件。在
touchstart
,
touchmove
或者
touchend
事件中的任意一个调用
event.preventDefault
,
mouse
事件 以及
click
事件将不会触发。
fastClick 在
touchend
阶段 调用
event.preventDefault
,然后通过
document.createEvent
创建一个
MouseEvents
,然后 通过
eventTarget.dispatchEvent
触发对应目标元素上绑定的
click
事件。