点击穿透与FastClick浅读
在移动端项目中,click事件的300ms延迟以及点击穿透的问题是两个最常见的问题,今天就来讨论讨论点击穿透问题
解析:
- 事件执行顺序,touchstart -> touchmove -> touchend -> click
- 如果某个超链接上面盖了一层蒙板,在click之前之前这层蒙板消失了,那么到执行click的事件就会加在超链接上面
而有些框架的tap事件为了解决click的300ms延迟就是用touchstart与touchend事件兼容模拟click事件从而解决click事件在移动端的300ms延迟问题。
FastClick解决方法
FastClick解决300ms延迟问题:
使用touchend以及touchstart兼容产生一个事件对象,然后通过方法sendClick来产生click模拟对象。源码如下
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);
};
FastClick解决点击击穿
在没有标记使用click的元素上,阻止click事件的派发,即阻止事件冒泡。将click事件在外层父盒子就隔断。源码如下
if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
// Prevent any user-added listeners declared on FastClick element from being fired.
if (event.stopImmediatePropagation) {
event.stopImmediatePropagation();
} else {
// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
event.propagationStopped = true;
}
// Cancel the event
event.stopPropagation();
event.preventDefault();
return false;
}
总结
在项目中,某些用touchend事件作为click事件补充的兄弟,点击穿透的事情你遇见了吗?如果用到touch事件,在一些效果实现上面,使用touchstart事件会比touchend事件给人的感觉灵敏!