移动端点透本质是touchend后300ms才触发click,此时上层已移除导致click落到底层;核心解法是禁用click模拟(如touch-action: manipulation)或在touchend中preventDefault()拦截。

移动端点透问题本质是 touch 事件与 click 事件的时序差异导致的——touchend 触发后约 300ms 才模拟出 click,此时上层遮罩已移除,click 落在了底层元素上。解决核心不是“阻止事件”,而是切断或延迟这个误触发链。
禁用默认 click 模拟(最常用)
给遮罩层或弹窗容器添加 CSS 属性,直接禁用浏览器的 click 模拟行为:
- touch-action: manipulation:告诉浏览器该区域只做平移/缩放,不触发 click 模拟(兼容性好,iOS 9.1+/Android 4.4+ 支持)
-
pointer-events: none:适用于完全不需要交互的遮罩层(注意:子元素需显式设为
pointer-events: auto才能响应) - 避免同时使用
cursor: pointer或:active伪类,它们可能隐式触发 click 行为
主动拦截并取消后续 click
在 touchend 阶段提前判断并阻止潜在的穿透 click:
- 监听遮罩层的
touchend,立即调用event.preventDefault() - 配合
event.stopPropagation()防止冒泡到 body 或父容器 - 更稳妥的做法:在 touchend 后 300ms 内监听 document 的
click,检查 target 是否在遮罩下方,是则stopImmediatePropagation()
重置焦点与滚动锚点(防连带穿透)
点透常伴随滚动穿透或焦点错位,需同步处理:
立即学习“Java免费学习笔记(深入)”;
- 弹窗打开时,记录当前
window.scrollY,设置body { position: fixed; top: -scrollY; width: 100%; } - 关闭弹窗后,恢复 body 样式,并用
window.scrollTo(0, scrollY)回滚 - 若弹窗内有 input,关闭前主动 blur,避免键盘收起后页面自动滚动错位
LiteGraph.js 等复杂场景专用处理
对于节点编辑器这类多层 canvas 应用,需结合框架机制:
- 在
LGraphCanvas.prototype._mouseup_callback中,增加对e.target的校验,排除非 canvas 区域的点击 - 上下文菜单关闭后,用
setTimeout(() => { canvas.focus(); }, 0)抢占焦点,防止 click 落入节点 - 拖拽结束时,临时禁用 canvas 的
mousedown监听 100ms,跳过 click 延迟窗口


















