移动端点击穿透问题


前言

做过移动端H5页面的同学肯定知道,移动端web的事件模型不同于PC页面的事件。看了一些关于touch事件的文章,我想再来回顾下touch事件的原理,为什么通过touch可以触发click事件,touch事件是不是万能的以及它可能存在的问题。

touch事件的来源

手机上没有鼠标,所以就用触摸事件去实现类似的功能。touch事件包含touchstart、touchmove、touchend,注意手机上并没有tap事件。手指触发触摸事件的过程为:touchstart -> touchmove -> touchend。

点击穿透的原因

因为Safari浏览器的300ms延迟的问题(在touchend后等待300ms确认没有双击就去触发click事件),当出现一个mask遮罩层的你去点击这个mask,然后mask消失300ms后会触发click,但是mask已经消失就会触发mask下方绑定有click事件的元素(也就是下层绑定了click事件或click时会触发的事件(focus focusout)的元素,或点击时有默认形为的标签元素,如a input等。)

解决办法

  1. 使用fastclick库,其实现思路是,取消 click 事件(参看源码 164-173 行),用 touchend 模拟快速点击行为(参看源码 521-610 行)。从此所有点击事件都使用click,不会出现“穿透”的问题,并且没有300ms的延迟。解决穿透的demo
FastClick.attach(document.body);
  1. CSS3的 pointer-events 属性
属性 含义
auto 默认值,鼠标或触屏事件不会穿透当前层
none 元素不再是target,监听的元素变成了下层的元素(如果子元素设置成 auto,点击子元素会继续监听事件)
  1. 遮挡
    1. 使mask在300ms之后消失掉(加些动画效果使他消失变慢)。
    2. 不用延时动画,我们还可以动态地在触摸位置生成一个透明的元素,这样当上层元素消失而延迟的click来到时,它点击到的是那个透明的元素,也不会“穿透”到底下。在一定的timeout后再将生成的透明元素移除。

results matching ""

    No results matching ""