单靠 user-select: none 无法禁用长按菜单,必须组合 -webkit-touch-callout: none 与全前缀 user-select 声明,并在微信等定制 webview 中加 js 拦截。

单靠 user-select: none 无法禁用长按菜单,它只阻止文本选中,不干预系统级上下文菜单(如“复制”“保存图片”)。真正起效必须组合 -webkit-touch-callout: none + 全前缀 user-select 声明,并在微信等定制 WebView 中加 JS 拦截。
为什么 user-select: none 单独写没用
浏览器把「长按选中文本」和「长按唤出系统菜单」当成两件事处理:user-select: none 只干预前者。iOS Safari 和 Android Chrome 在长按时会独立检测可交互内容(哪怕文字不可选),仍可能弹出菜单。
- 现象:加了
select-none或user-select: none,但长按图片、链接、带文字的<span></span>还是弹窗 -
<input>、<textarea></textarea>、contenteditable元素上设user-select: none会被忽略——这是浏览器强制行为,不是 bug - 父级设置了
user-select: text会继承覆盖子元素的-webkit-touch-callout: none
-webkit-touch-callout: none 是 iOS 禁菜单的关键
这个属性专为 iOS WebKit 内核设计,控制长按时是否显示原生呼叫菜单(callout),对图片、链接、文字块都生效。Android 不识别它,但加了也无害。
- 值只能是
none或default,别写成-webkit-touch-callout: disable - 必须放在 CSS 声明的第一行,否则某些 iOS WebView 会忽略
- 只在 iOS Safari 及所有基于 WebKit 的 iOS 内置浏览器(微信、钉钉、企业微信等)起作用
- 单独使用在 iOS 13+ 和微信 X5 内核中基本失效,必须配合
user-select声明
跨平台真正生效的最小 CSS 组合
要覆盖 iOS、Android、PC 触控设备,得把各引擎前缀打全,且顺序不能错(后声明的优先级更高):
.prevent-longpress {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
- 不要全局写
* { ... }—— 会误伤<input>的光标定位和可编辑区域 - 若用了
pointer-events: none,记得它会同时禁掉点击,不是“仅禁长按” - Tailwind 用户需手动加
[--webkit-touch-callout:none](启用 JIT 模式才支持)
微信 WebView 等定制内核必须加 JS 兜底
微信 X5、QQ 浏览器、部分安卓厂商 WebView 对 CSS 支持不稳定,-webkit-touch-callout 常被无视。
- 给目标元素绑定
touchstart并调用e.preventDefault() - 同时监听
contextmenu事件并e.preventDefault() - 不要在
上全局监听touchstart,否则滚动、输入框聚焦都会异常 - 排除表单控件:
if (!e.target.matches('input, textarea, select, [contenteditable]')) { e.preventDefault(); }
所有前端手段都无法阻止截图、录屏、DevTools 查看 network 或 elements 面板抓图——CSS 层面能做到的,始终只是「降低触发概率」,不是「绝对禁用」。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











