简介
这篇文章主要是一些总结的移动端开发的一些坑,以及爬坑方法。
正文
ios-webview点击事件(click)延迟
在pc端开发时常用的点击事件中使用最对的可能是click,但是在移动端的网页中,默认是拥有双击缩放这个功能的,那么为了使这个功能生效,页面通常是在第一次点击完之后先不触发click事件,而是等待300ms之后看是否有第二次点击,有的话就缩放,没有就触发点击事件,这就造成了300ms延迟。
幸运的是谷歌浏览器将在包含 width=device-width 或者置为比 viewport 值更小的页面上禁用双击缩放。当然,没有双击缩放就没有 300 毫秒点击延迟。随后各大浏览器也相应支持,也包括ios的safari。但是兼容性不是很好,例如ios的webview仍然有300ms的延迟,原因未知,等我研究完ios开发再来回答。
解决方法:
touchTap
但此时又会出现一个新的问题,tap事件穿透。
tap事件的原理是监听body上的touchstart,touchmove以及touchend来进行判断,那么正常情况下tap事件还没有冒泡到body时,click事件就触发了。但是当页面有300ms延迟是,就会造成事件穿透。当然解决有两个办法,最简单也是副作用最大的办法是将页面所有click事件全部切换成touchTap事件,第二个就是使用fastclick。
fastclick
打开fastclick源码可以看到有一个sendClick方法。
/**
* Send a click event to the specified element.
*
* @param {EventTarget|Element} targetElement
* @param {Event} event
*/
FastClick.prototype.sendClick = function(targetElement, event) {
var clickEvent, touch;
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
if (document.activeElement && document.activeElement !== targetElement) {
document.activeElement.blur();
}
touch = event.changedTouches[0];
// Synthesise a click event, with an extra attribute so it can be tracked
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
可以看出这里是用document的createEvent
API模拟了一次点击事件。紧接着我们在FastClick.prototype.onTouchEnd
这个方法下面发现这里调用了this.sendClick
方法,由此可以看出fastclick的原理就是在touchEnd事件中增加判断,看是否是一次移动端的点击事件,如果是,就主动出发click,这样既解决了移动端300ms延迟,又解决了事件穿透,是一个比较好的解决方案。