移动端容易碰到的点击穿透的坑
关于那些点击穿透的坑
之前在做嵌入微信的移动端的项目的时候遇到了一个点击穿透的坑,由于忙着项目一直没有时间进行总结,现在终于看到了不用每天加班的希望曙光,在这个偷偷得来的闲暇时光把这个坑好好的捋一捋:
所谓的点击穿透最明了的一点是会出现在移动端,并且是使用click的时候。点击穿透的意思也就是:比如我设计了一个分类的按钮(以下为小btn),点击的时候会出现一个弹出框,内容是我项目中的所有分类信息,我需要选择我想进入的那个分组点击进入,这个时候问题就出现了,若是弹窗下边刚好覆盖了一个a标签(以下为小a),并且是有跳转,那么你会惊奇的发现,你首先会进入那个你想要进入的地方,但是之后会速度的跳转到被覆盖的a标签跳转的地方。这么一来就尴尬了,你想要进入的地方变成了一个中转站,而你并没有想要去的地方变成了最终下车的地方。
在最开始的时候并没有意识到是点击穿透的问题,还以为是因为给小btn设置的z-index不够,所以才导致了小a的href属性被触发,然后就改变代码布置啊,改成div的事件触发,在满心期待的时候又被打脸,没用,依然是跳转。这就尴尬了,为了代码的规范性,改回来吧,有吭哧吭哧的改回来原本的代码设置,继续使用小a触发跳转。之后没办法就一直找问题啊,为什么总是能触发到下边的小a呢,说来也怪,测试的时候基本上已经处于疯癫的状态了,同一个东西放在Safari上没有任何问题,但是用微信打开就是各种乱跳啊,我疑惑了很久,忽然在做另一个东西的时候想到了是因为微信使用的浏览器是默认的腾讯内部推广的X5qq浏览器,他们自己的设置的原因,但是项目又必须是微信中打开,这就尴尬了。在实在要整个人疯掉的时候,忽然脑子一热想到了一个词---点击穿透(很早之前在地铁上听两个貌似也是程序猿的帅锅聊天时聊到的,当时额还是一个初入门的孩子,不过也得感谢自己的灵机一动啊),然后我就果断网路了一下这个词语啊,期待终于实现了一次,让我找到了一个解决办法,fastClick(https://github.com/ftlabs/fastclick/感兴趣的孩子可以去看下),已经试验,果然是老天眷顾我啊,当时被直播折磨疯了的我已经快要没有任何耐心再纠结这个了啊。
github上关于这个介绍如下:FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a click
event on mobile browsers. The aim is to make your application feel less laggy and more responsive while avoiding any interference with your current logic.
github上也说了关于这个延时存在的原因,当时为了监测用户是否进行了双点击操作才对click事件进行了300ms的延时,但是这样的延时刚刚也就造成了这个点击穿透bug,实在是有够头疼;
关于官网上介绍是这么说的:
Why does the delay exist?
According to Google:
...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
其实明白是click的延时造成的时候也试了一下zepto的tap,结果依然是存在的;
查了之后zepto的tap通过兼听绑定在document上的touch事件来完成tap事件的模拟的,及tap事件是冒泡到document上触发的,再点击完成时的tap事件(touchstart\touchend)需要冒泡到document上才会触发,而在冒泡到document之前,用户手的接触屏幕(touchstart)和离开屏幕(touchend)是会触发click事件的,因为click事件有延迟触发(这就是为什么移动端不用click而用tap的原因)(大概是300ms,为了实现safari的双击事件的设计),所以在执行完tap事件之后,弹出来的选择组件马上就隐藏了,此时click事件还在延迟的300ms之中,当300ms到来的时候,click到的其实不是完成而是隐藏之后的下方的元素,如果正下方的元素绑定的有click事件此时便会触发,如果没有绑定click事件的话就当没click,但是正下方的是input输入框(或者select选择框或者单选复选框),点击默认聚焦而弹出输入键盘,也就出现了点透现象;
最后使用了fastClick这个工具真的是及时的解决的问题啊,这边领导等着看结果,这边一直出不来,脑子都要抽掉了,哎,真的没有了点击穿透啊!!!
使用方法可以参考之上给出的github的地址,也可以看我下边罗列的方法:
<script type='application/javascript' src='/path/to/fastclick.js'></script>
如果使用原生:if ('addEventListener' in document) { document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false); }
我是使用的jq:$(function() { FastClick.attach(document.body); });
更多框架中使用或者是其他的方法可以参考这个地址了:https://github.com/ftlabs/fastclick/