说说移动端web开发中的点击穿透问题

最近一直在忙于一个无线端的项目,因为以前主要工做都是在桌面端,移动端接触的比较少,因此中间遇到了不少的坑,作一个简单的记录。segmentfault

问题背景

需求中有这样的一个功能,点击取件信息的时候会弹出一个地址列表的浮层,用户选择地址以后会将具体的地址回填到取件信息当中去。按道理讲,这是一个很是简单的功能,但是在开发过程当中却遇到了不少很是诡异的事情。浏览器

初始的代码是这么写的:post

var pickupInfo = $("#pickupInfo");  
pickupInfo.on("tap", function () {
    var addressList = $("#addressList");
    addressList.show();
});  

window.addEventListener("message", function () {
    // 回填地址信息
});
// addressList 是一个浮层
$("#addressList li").on("click", function () {
    // 此处回填地址到取件信息中去  
    // 具体方式则是经过iframe的postMessage发送消息,pickupInfo那边接收消息后填充
});

为了更清楚的说明问题,此处删除了不少的业务逻辑。测试

在测试过程当中就发现了一个诡异的问题,在点击pickupInfo的时候,addressList浮层闪了一下就消失了,弹出addressList浮层后当即回填了地址信息。优化

由于一开始也没有太注意观察,跟代码的过程当中发现只要浮层一弹出,pickupInfo那边就当即收到了message事件信息。当时第一反应感受是地址列表那边出了问题,看了好几遍代码,一直没发现哪里有问题,也跟了几回,每次都是地址列表一弹出就当即触发了click事件。google

奇了个怪了!code

点击穿透

试着描述了下问题google了一把,多是描述的不太准确,啥也没搜着。没办法了,瞪大眼睛再操做一遍。这时候奇迹出现了,我发现每次点击pickupInfo,都在选中addressList中相对于屏幕与pickupInfo相同位置的地址。事件

查看了下事发地点的代码,而后在google中敲下了这几个字“移动端 tap”,一大堆的结果,看了几篇文章,终于找到了问题的答案。开发

先说说touch事件吧。get

咱们知道,PC上有鼠标事件,一次点击能够拆分红mousedown > click > mouseup 三步。移动端没有鼠标,可是有相似的触摸事件,用户的一次点击能够分为touchstart > touchmove > touchend。 虽然手机上没有mouse事件,可是手机依然能够响应mouse事件,为何呢?是经过touch事件来模拟的。有人曾经对比测试过手机上和PC上的mouse事件,发现手机上的mouse要慢一些,大概在300m左右。

再说说tap事件。

在PC端,咱们常常使用到click事件,对应到移动端,咱们使用tap事件。但原生的touch事件自己是没有tap的,也是经过模拟产生的。在Zepto中,若是在touchend事件响应250ms无操做后,会触发singleTap事件。

// trigger single tap after 250ms of inactivity
else {
    touchTimeout = setTimeout(function(){
        touchTimeout = null
        if (touch.el) touch.el.trigger('singleTap')
        touch = {}
    }, 250)
}

至此,点击穿透的缘由就明了了。

当pickupInfo监听的tap事件获得响应以后,会当即弹出addressList浮层,此时浏览器还会触发click事件,而此时原来的pickupInfo已经彻底被addressList遮罩,因此click事件就被触发在了与pickupInfo相同位置的addressList中对应的区域,也就正好响应了addressList中监听的click事件。

世事奈何如此之巧~

解决方案

问题清楚了,修改方法也就明确了,因为项目还在开发中,我的以为当前的方案还不是特别好,后续优化后再贴出来。这里贴篇文章,也来讲说touch事件与点击穿透问题,里面对touch和tap事件作了详细的说明,对点击穿透问题也提到了几个方案,能够参考。

小结

这两天一直在忙于赶开发进度,对于过程当中遇到的一些典型的问题作一些记录,算是一种沉淀吧~~

相关文章
相关标签/搜索