移动页面的点击穿透问题

点击穿透现象有3种:javascript

  • 点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件html

    蒙层的关闭按钮绑定的是touch事件,而按钮下面元素绑定的是click事件,touch事件触发以后,蒙层消失了,300ms后这个点的click事件fire,event的target天然就是按钮下面的元素,由于按钮跟蒙层一块儿消失了java

  • 跨页面点击穿透问题:若是按钮下面刚好是一个有href属性的a标签,那么页面就会发生跳转app

    由于 a标签跳转默认是click事件触发 ,因此原理和上面的彻底相同测试

  • 另外一种跨页面点击穿透问题:此次没有mask了,直接点击页内按钮跳转至新页,而后发现新页面中对应位置元素的click事件被触发了spa

  • 和蒙层的道理同样,js控制页面跳转的逻辑若是是绑定在touch事件上的,并且新页面中对应位置的元素绑定的是click事件,并且页面在300ms内完成了跳转,三个条件同时知足,就出现这种状况了.net

非要细分的话还有第四种,不过几率很低,就是新页面中对应位置元素刚好是a标签,而后就发生连续跳转了。。。诸如此类的,都是点击穿透问题code

解决方案

问题已经很明了了,有不少解决方案,但思路不外乎2种:htm

  1. 不要混用touch和clickblog

    既然touch以后300ms会触发click,只用touch或者只用click就天然不会存在问题了

  2. 吃掉(或者说是消费掉)touch以后的click

    依旧用tap,只是在可能发生点击穿透的情形作额外的处理,拿个东西来挡住、或者tap后延迟350毫秒再隐藏mask、pointer-events、在下面元素的事件处理器里作检测(配合全局flag)等等,能吃掉就行

详细解决方案

  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. 拿个东西来挡住

    比较笨的方法, 千万不要用

    叶小钗的“菊花”大法,更多信息请查看 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)

  4. tap后延迟350ms再隐藏mask

    改动最小,缺点是隐藏mask变慢了,350ms仍是能感受到慢的

    只须要针对mask作处理就行,改动很是小,若是要求不高的话,用这个比较省力

  5. pointer-events

    比较麻烦且有缺陷, 不建议使用

    mask隐藏后,给按钮下面元素添上 pointer-events: none; 样式,让click穿过去,350ms后去掉这个样式,恢复响应

    缺陷是mask消失后的的350ms内,用户能够看到按钮下面的元素点着没反应,若是用户手速很快的话必定会发现

  6. 在下面元素的事件处理器里作检测(配合全局flag)

    比较麻烦, 不建议使用

    全局flag记录按钮点击的位置(坐标点),在下面元素的事件处理器里判断event的坐标点,若是相同则是那个可恶的click,拒绝响应

    上面说的只是想法,没测试过,实在不行就用记录时间戳判断,等待350ms,这样就和 pointer-events 差很少

  7. fastclick

    好用的解决方案,不介意多加载几KB的话, 不建议使用 ,由于有人遇到了bug,更多信息请查看: Fastclick 致使click事件触发两次的问题

    首先引入fastclick库,再把页面内全部touch事件都换成click,其实稍微有点麻烦,建议引入这几KB就为了解决点透问题不值得,不如用第一种方法呢

相关文章
相关标签/搜索