数约定,包括双击缩放,几乎如今全部的移动端浏览器都有这个功能。 300 毫秒延迟的主要缘由是解决双击缩放(double tap to zoom)。双击缩放,顾名思义,即用手指在屏幕上快速点击两
次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢?
假定这么一个场景。用户在 iOS Safari 里边点击了一个连接。因为用户能够进行双击缩放或者双击滚动的操做,当用
户一次点击屏幕以后,浏览器并不能马上判断用户是确实要打开这个连接,仍是想要进行双击操做。所以,iOS Safari就等待300毫秒,
以判断用户是否再次点击了屏幕。鉴于iPhone的成功,其余移动浏览器都复制了 iPhone Safari 浏览器的
解决方案:fastclick库或者使用touchstart事件代替点击事件
FastClick 是 FT labs 专门为解决移动端浏览器 300ms 点击延迟问题所开发的一个轻量级的库。浏览器
基本原理:FastClick 的实现原理是在检测到 touchend 事件的时候,会经过 DOM 自定义事件当即出发模拟一个click事件,并把浏览器在 300ms 以后真正的 click 事件阻止掉。this
fastClick的核心代码spa
FastClick.prototype.onTouchEnd = function (event) { // 一些状态监测代码 // 从这里开始, if (!this.needsClick(targetElement)) { // 若是这不是一个须要使用原生click的元素,则屏蔽原生事件,避免触发两次click event.preventDefault(); // 触发一次模拟的click this.sendClick(targetElement, event); } }
这里能够看到,FastClick 在 touchEnd 的时候,在符合条件的状况下,主动触发了click事件,这样避免了浏览器默认的300ms 等待判断。为了防止原生的 click 被触发,这里还经过 event.preventDefault() 屏蔽了原生的click事件。prototype
经过 sendClick 模拟 click 事件:code
FastClick.prototype.sendClick = function (targetElement, event) { // 这里是一些状态检查逻辑 // 建立一个鼠标事件 clickEvent = document.createEvent('MouseEvents'); // 初始化鼠标事件为click事件 clickEvent.initMouseEvent( this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null ); // fastclick的内部变量,用来识别click事件是原生仍是模拟 clickEvent.forwardedTouchEvent = true; // 在目标元素上触发该鼠标事件, targetElement.dispatchEvent(clickEvent); }
就目前而言,FastClick 很是实际地解决 300ms 点击延迟的问题。惟一的缺点可能也就是该脚本的文件尺寸 (尽管它只有 10kb)。blog
能不能直接用 touchstart 代替click呢,
答案是不能,使用 touchstart 去代替click事件有两个很差的地方。
第一:touchstart 是手指触摸屏幕就触发,有时候用户只是想滑动屏幕,却触发了 touchstart 事件,这不是咱们想要的结果;
第二:使用 touchstart 事件在某些场景下可能会出现点击穿透的现象。事件