1.点击穿透问题:
1.点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件。蒙层的关闭按钮绑定的是touch事件,而按钮下面元素绑定的是click事件,touch事件触发之后,蒙层消失了,300ms后这个点的click事件fire,event的target自然就是按钮下面的元素,因为按钮跟蒙层一起消失了
2.跨页面点击穿透问题:如果按钮下面恰好是一个有href属性的a标签,那么页面就会发生跳转,因为a标签跳转默认是click事件触发,所以原理和上面的完全相同
3.另一种跨页面点击穿透问题:这次没有mask了,直接点击页内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了。和蒙层的道理一样,js控制页面跳转的逻辑如果是绑定在touch事件上的,而且新页面中对应位置的元素绑定的是click事件,而且页面在300ms内完成了跳转,三个条件同时满足,就出现这种情况了
2.如何解决?
1.只用touch。最简单的解决方案,完美解决点击穿透问题。把页面内所有click全部换成touch事件(touchstart、’touchend’、’tap’),需要特别注意a标签,a标签的href也是click,需要去掉换成js控制的跳转,或者直接改成span + tap控制跳转。如果要求不高,不在乎滑走或者滑进来触发事件的话,span + touchend就可以了,毕竟tap需要引入第三方库。不用a标签其实没什么,移动app开发不用考虑SEO,即便用了a标签,一般也会去掉所有默认样式,不如直接用span
2.只用click。下下策,因为会带来300ms延迟,页面内任何一个自定义交互都将增加300毫秒延迟,想想都慢。不用touch就不会存在touch之后300ms触发click的问题,如果交互性要求不高可以这么做,强烈不推荐,快一点总是好的。
3.tap后延迟350ms再隐藏mask。改动最小,缺点是隐藏mask变慢了,350ms还是能感觉到慢的,只需要针对mask做处理就行,改动非常小,如果要求不高的话,用这个比较省力。
4.pointer-events。比较麻烦且有缺陷,不建议使用,mask隐藏后,给按钮下面元素添上pointer-events: none;样式,让click穿过去,350ms后去掉这个样式,恢复响应。缺陷是mask消失后的的350ms内,用户可以看到按钮下面的元素点着没反应,如果用户手速很快的话一定会发现。
5.在下面元素的事件处理器里做检测(配合全局flag)。比较麻烦,不建议使用全局flag记录按钮点击的位置(坐标点),在下面元素的事件处理器里判断event的坐标点,如果相同则是那个可恶的click,拒绝响应。上面说的只是想法,没测试过,实在不行就用记录时间戳判断,等待350ms,这样就和pointer-events差不多。