viewport meta 标签必须含 initial-scale=1.0 才生效,否则 ios safari 9.2 及更早版本、uc/qq 浏览器旧版仍会延迟 300ms;user-scalable=no 或 maximum-scale=1.0 才真正禁用双击缩放,minimum-scale=1.0 单独无效且拼写错误会导致失效;该标签须静态置于 head 内;touch-action: manipulation 是当前最稳妥的 css 解法,仅作用于有点击意图的元素,ie 需加 -ms- 前缀;fastclick 与 touch-action 不可共存;pwa 添加到主屏幕后仍需按钮级 touch-action 保障无延迟。

viewport meta 标签必须含 initial-scale=1.0 才生效
只写 <meta name="viewport" content="width=device-width"> 不会消除延迟——iOS Safari 9.2 及更早版本、UC/QQ 浏览器旧版仍会等满 300ms。浏览器需要明确的缩放锚点,initial-scale=1.0 是触发双击判定优化的硬性条件。
-
user-scalable=no或maximum-scale=1.0才真正关闭双击缩放判断;minimum-scale=1.0单独无效,拼错成minimun-scale会导致整个 meta 失效 - 该标签必须静态写在
内,动态插入或放在里解析失败 - 若页面需保留图片双指放大能力,就不能用
user-scalable=no,得靠后续方案补位
touch-action: manipulation 是当前最稳妥的 CSS 解法
它不是“禁用所有手势”,而是告诉浏览器:“此处只需响应点击和单指纵向滚动”,语义准确、滚动不卡、兼容 iOS 9.3+ 和 Chrome 36+。
- 只加在有点击意图的元素上,比如
<button></button>、<div class="card" onclick="...">;不要设在 <code>html或body上,否则页面无法滚动 - 原生可点击元素(
<button></button>、<a></a>、<input type="button">)默认已有该行为,除非你写了display: inline或显式设了touch-action: auto - IE10/11 需加前缀:
-ms-touch-action: manipulation - 排查方法:控制台输入
window.FastClick,返回构造函数说明还在运行;全局搜索FastClick.attach或new FastClick() - 若已用
touch-action,直接删掉 FastClick 初始化代码,无需替换逻辑 - 老项目若保留 FastClick,必须确保它只挂载在
document.body上,不能挂到#app或局部容器,否则动态弹层按钮会失效 - 临时屏蔽方案:
pointer-events: none加在弹层消失前的过渡阶段 - 更可靠做法:改用
pointerdown+preventDefault()替代click,并配合 CSStouch-action: manipulation - PWA 添加到主屏幕后,即使 viewport 完整,部分 iOS 设备仍出现延迟,此时必须加
touch-action到按钮级样式,仅靠 HTML 不够
别让 FastClick 和 touch-action 共存
FastClick 用 JS 模拟 click 并阻止原生 click,touch-action: manipulation 让原生 click 立即触发——两者机制冲突,共存后常见按钮无响应、事件重复、顺序错乱。
穿透问题比延迟更难调试,且无法靠 JS 拦截
哪怕 touch-action 已生效,只要上层弹层在 touchend 后立刻 display: none 或移除,300ms 后原生 click 仍会落到下层按钮上——这是浏览器事件派发时序决定的,JS 无法 cancel。











