移动端页面点击穿透问题

简介: 一、click与300ms延迟    移动端浏览器提供了一个特殊的功能:双击放大300ms的延迟就是来自于这里,用户碰触页面之后,需要等待一段时间来判断是不是双击(double tap)动作,而不是立即响应单击(click),等待的这段时间大约是300ms。

一、click与300ms延迟

    移动端浏览器提供了一个特殊的功能:双击放大

300ms的延迟就是来自于这里,用户碰触页面之后,需要等待一段时间来判断是不是双击(double tap)动作,而不是立即响应单击(click),等待的这段时间大约是300ms。

之前有过简单介绍(黯羽轻扬:HTML5触摸事件

移动事件提供了touchstart、touchmove、touchend却没有提供tap支持,主流框架(库)都是手动实现了自定义tap事件,以消除300ms延迟,提高页面响应速度,对于简单的页面,可以把touchstart或者touchend当做tap来用,但是存在一些问题,比如手直接触目标元素,按住不放,慢慢移除响应区域,会触发touchstart事件执行对应的事件处理器(本不应该触发),touchend事件也存在类似的问题。

此外,使用原生touch事件也存在点击穿透的问题,因为click是在touch系列事件发生大约300ms才触发的,混用touch和click肯定会导致点透问题,下面详细介绍

二、点击穿透问题

点击穿透现象有三种

    *点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件
蒙层关闭按钮绑定的是touch事件,而按钮下边元素绑定的是click事件,touch事件触发之后,蒙层消失了,300ms后这个点的click事件fire,event的target自然就是按钮下面的元素,因为按钮跟蒙层一起消息了。

    *跨页面点击穿透事件:如果按钮下面恰好是一个href属性的a标签,那么页面就会法神跳转,因为a标签跳转默认是click事件触发,所以原理和上面的完全相同

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

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

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

三、为什么会出现点透

click延迟、延迟、还是延迟

在移动端不使用click而用touch事件代替触摸是因为click事件有着明显的延迟,具体touchstart与click的区别如下:

    *touchstart:在这个DOM(或者冒泡到这个DOM)上手指触摸开始即能立即出发

    *click:在这个DOM(或者冒泡这个DOM)上手指触摸开始,且手指未在屏幕上移动(某些<a href=”http://www.it165.net/edu/ewl/” target=”_blank” class=”keylink”>浏览器</a>允许移动一个非常小的位移值),且在这个DOM元素上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短(某些浏览器不检测间隔时间,也会触发click)才能触发

也就是说,事件的触发事件按照由早到晚排列为:touchstart早于touchend早于click。亦即click的触发是有延迟的,这个时间大概在300ms左右(即使给元素绑定的是touch事件,touchstart=>touchend=>click,click事件依然会被触发)

由于我们在touchstart阶段就已经隐藏了罩层A,当click被触发的时候,能够被点击的元素则是罩层下面的B元素绑定的事件,根据click事件的触发规则:

只有在被触发的时候,当前有click事件的元素显示,且在面朝用户的最前端时,才出发click事件。

由于B绑定了click事件(或者B本身默认存在click事件),所以B的click事件被触发,产生了点透的情况。

解决方案

对于B元素本身没有默认click事件的情况(无a标签等),应统一使用touch事件,统一代码风格,并且由于click事件在移动端的延迟要大很多,不利于用户体验,所以关于触摸事件应尽量使用touch相关事件。

对于B元素本身存在默认click事件的情况,应及时取消A元素的默认点击事件,从而阻止click事件的产生。即应在上例的handle函数中添加代码如下:

img_13849ed4242d4f29becf3297b0fba41a.png

对于遮盖浮层,由于遮盖浮层的点击即使有小延迟也是没有关系的,反而会有疑似更好的用户体验,所以这种情况,可以针对遮盖浮层自己采用click事件,这样就不会出现点透问题。

四、解决方案

问题已经很明了了,有很多解决方案,但是思路不外乎2种:
1、不要混用touch和click

        既然touch之后300ms会触发click,只用touch或者只用click自然不会存在问题

2、吃掉或者消费掉touch之后的click

        依旧用tap,只是在可能发生点击穿透的情形做额外的处理,拿个东西来挡住或者tap后延迟350ms在隐藏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延迟,页面内任何一个滴定仪监护都将增加300ms延迟,想想都慢

不用touch就不会存在touch之后300ms触发click的问题,如果交互性要求不高可以这么做, 强烈不推荐 ,快一点总是好的

3、拿个东西来挡住

比较笨的方法,不推荐用

4、tap后延迟350ms在隐藏mask

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

只需要针对mask做处理就行,改动非常小,如果要求不高的话,用这个比较省力

5、pointer-events

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

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

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

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

6、比较麻烦, 不建议使用

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

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

7、fastclick

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

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

参考文档:http://www.uedsc.com/through-the-click-point-in-the-development-of-web.html

相关文章
|
6月前
|
Web App开发 前端开发 异构计算
前端如何实现网页变灰功能?
前端如何实现网页变灰功能?
122 0
|
3月前
|
前端开发 UED
墙裂推荐!Vue3 实现B站页面滚动开启小屏播放功能,超简单!!
墙裂推荐!Vue3 实现B站页面滚动开启小屏播放功能,超简单!!
|
6月前
|
小程序
在微信小程序中打开的页面不能超过10个,达到10个页面后,就不能再打开新的页面
在微信小程序中打开的页面不能超过10个,达到10个页面后,就不能再打开新的页面
431 1
|
6月前
|
Android开发
热点共享蓝条下压,导致页面底部按钮显示不全的完美解决方案
热点共享蓝条下压,导致页面底部按钮显示不全的完美解决方案
34 0
|
前端开发 JavaScript
【项目笔记】:elementui下拉框数据太多造成页面卡顿怎么解决?
针对前端下拉框数据过多造成页面卡顿,元芳你怎么看?
210 2
|
前端开发 JavaScript API
浅谈移动端页面无刷新跳转问题的解决方案
浅谈移动端页面无刷新跳转问题的解决方案
130 0
|
前端开发 JavaScript
漏刻有时后台左侧菜单默认隐藏的解决方案
漏刻有时后台左侧菜单默认隐藏的解决方案
70 0
|
小程序 JavaScript
微信小程序实现左右滑动进行切换数据页面(touchmove)
微信小程序实现左右滑动进行切换数据页面(touchmove)
1325 0
|
前端开发 IDE 开发工具
「趣学前端」日常浏览的页面为什么可以五颜六色
用技术实现梦想,用梦想打开创意之门。为了给不懂技术的朋友讲解日常开发中怎么实现网页的效果,我准备出一个系列。
155 1
|
移动开发 前端开发 IDE
「趣学前端」日常浏览的页面是怎么实现出来的
用技术实现梦想,用梦想打开创意之门。为了给不懂技术的朋友讲解日常开发中怎么实现网页的效果,我准备出一个系列。
144 1