Zepto tap 的"点透"问题
1. 什么是"点透"?
在列表页面上创建一个弹出层,弹出层有个关闭按钮。点击这个按钮关闭弹出层后,按钮正下方的内容也会执行点击事件(或打开链接)。这种现象被定义为"点透"。
2. 点透原因
- Zepto 的
tap通过监听绑定在document上的 touch 事件模拟。 tap事件是冒泡到document上触发的。- 在
tap完成时(touchstart/touchend),需要冒泡到document才触发;而冒泡到document之前,touchstart/touchend会先触发click。 - 因为
click有大约 300ms 延迟(为实现 Safari 的双击事件),而tap立即触发,所以看起来就像"穿透"。
3. 解决方案
方案一:使用 FastClick
window.addEventListener('load', function () {
FastClick.attach(document.body);
}, false);
// 或者 require
var FastClick = require('fastclick');
FastClick.attach(document.body, options);
方案二:用 touchend 代替 tap,并 preventDefault()
$('#cbFinish').on('touchend', function (event) {
// 很多处理比如隐藏什么的
event.preventDefault();
});
方案三:延迟一定时间(300ms+)处理事件
$('#cbFinish').on('tap', function (event) {
setTimeout(function () {
// 很多处理比如隐藏什么的
}, 320);
});
这种方法可以和 fadeIn / fadeOut 等动画结合使用,做出过渡效果。
4. 现代方案
现代移动端一般直接用 click 事件 + 阻止冒泡,或在 Vue/React 等框架中用官方推荐的 @click 即可避免此问题(框架的事件系统通常已经处理过)。如果必须用 tap,搭配 pointer-events / touch-action 也是可行的兜底策略。
来源整理自:我的有道云笔记



