欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

移动页面事件穿透/点击穿透问题

程序员文章站 2022-03-23 13:47:19
一、背景 博主所负责其中一个项目是web页面,在移动端上出现了事件穿透问题,开发介绍问题原因后,发觉是移动web一个知识点,值得记录一下。 二、click与300ms延迟 移动浏览器提供一个特殊的功能:双击(double tap)放大 300ms的延迟就来自这里,用户触碰页面之后,需要等待一段时间来 ......

一、背景

博主所负责其中一个项目是web页面,在移动端上出现了事件穿透问题,开发介绍问题原因后,发觉是移动web一个知识点,值得记录一下。

二、click与300ms延迟

移动浏览器提供一个特殊的功能:双击(double tap)放大

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

  1. 移动端touch事件提供:touchstarttouchmovetouchend,却没有tap支持;
  2. 主流框架/库都是手动实现了tap事件,以求消除300ms延迟,提高页面响应速度
  3. 对于简单的页面,可以把 touchstart 或者 touchend 当作tap来用,但存在一些问题,比如手指接触目标元素,按住不放,慢慢移出响应区域,会触发 touchstart 事件执行对应的事件处理器(本不应该触发),touchend 事件也存在类似的问题。
  4. 使用原生的touch事件存在点击穿透的问题,因为click是在touch系列事件发生后大约300ms才触发,混用touchclick肯定会导致事件穿透。
  5. 手机上响应click事件有300ms的延迟,会有响应慢/延迟的感觉,因此很多移动页面会使用touch/tap事件。

三、tap事件

用过zepto或者kissy等移动端js库的人肯定对tap事件不陌生,我们做pc页面时候绑定click,相应地手机页面就绑定tap。但原生的touch事件本身是没有tap的,js库提供的tap事件都是模拟出来的。

zepto中对tap事件处理:如果在touched响应250ms无操作后,则触发singletap。即事件触发顺序为:touch-tap-click。

三、点击穿透问题

点击穿透现象有3种:

  • 点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件。
    • 解析:蒙层的关闭按钮绑定的是touch事件,而按钮下面元素绑定的是click事件。touch事件触发之后,蒙层消失了,300ms后这个点击的click事件fire,event的target自然就是按钮下面的元素。
  • 跨页面点击穿透问题:如果按钮下面恰好是有href属性的a标签,那么页面就会发生调整。因为a标签跳转默认是click事件触发。原因同上。
  • 第三种:这次没有mask,直接点击页面内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了。
    • 解析:和蒙层的道理一样,js控制页面跳转的逻辑如果是绑定在touch事件上的,而且新页面中对应位置的元素绑定的是click事件,而且页面在300ms内完成了跳转,三个条件同时满足,就出现这种情况。

四、解决方案

思路:

  1. 不要混用touch和click:touch之后300ms会触发click,只有touch或者只用click就自然不会存在问题。

  2. 吃掉/消费掉touch之后的click

    依旧使用tap,只是在可能发生点击穿透的情形下做额外的处理,拿个东西来挡住、或者tap后延迟350ms再隐藏mask、pointer-events、在下面元素的事件处理器里做检测。

我们对事件响应速度要求不高,最后是通过延迟隐藏/关闭mask/弹窗解决的,简单可控哈。

参考: