touch-action不是制作手势的工具,而是控制浏览器是否接管触摸行为的策略开关;它通过none、pan-x/pan-y、pinch-zoom、manipulation等值决定滚动、缩放等默认行为是否被禁用或保留,需配合JS事件监听与preventDefault才能实现自定义交互。

touch-action 不是用来“制作手势”的,它只是告诉浏览器:这个区域的手指操作该由谁来处理——是浏览器默认滚动缩放,还是交给你用 JavaScript 自己接管。想靠它实现双指缩放、长按菜单或滑动翻页?做不到。
touch-action 的取值和实际效果
它的值决定浏览器是否劫持原生触摸行为,常见组合有:
-
touch-action: none:完全禁用浏览器默认触摸响应(滚动、缩放、双击放大),所有 touch 事件都能触发,适合自研手势库 -
touch-action: pan-x或pan-y:只允许对应方向的原生滚动,其余方向交给 JS;比如轮播图容器设pan-x,用户左右滑能滚动,但上下拖不会触发页面滚动 -
touch-action: pinch-zoom:仅允许双指缩放(需配合meta viewport中user-scalable=yes),不支持单指拖拽或旋转 -
touch-action: manipulation:等价于pan-x pan-y pinch-zoom,是移动端最常用的安全兜底值,兼顾可滚动性和点击延迟优化
为什么加了 touch-action 还没反应?
常见失效原因不是写错了值,而是被更高优先级规则覆盖或未生效于目标元素:
- 父元素设置了
touch-action: none,子元素即使设成pan-x也会被继承压制(touch-action可被继承,且不支持unset覆盖) - 元素没有尺寸或
overflow: hidden导致 pan 行为无处发生(比如空 div 上设pan-y,手指划过也不会滚动) - 在 iOS Safari 中,
pinch-zoom必须配合<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">才生效,缺一不可 - 用了
position: fixed或transform: translateZ(0)的元素,在部分安卓 WebView 中可能忽略touch-action
和 JavaScript 手势监听怎么配合?
关键原则:先用 touch-action “让出控制权”,再用 JS 接手。否则 touchstart/touchmove 可能根本收不到,尤其在 Chrome for Android 上:
立即学习“前端免费学习笔记(深入)”;
- 要做自定义滑动切换,容器必须设
touch-action: none,否则touchmove会被浏览器吞掉用于滚动 - 如果只想禁用缩放但保留滚动,别写
none,改用pan-x pan-y—— 否则 iOS 会连click事件都延迟 300ms - 监听
touchmove时记得加event.preventDefault()(前提是touch-action已设为none或对应方向受限),不然滚动仍会穿透 - 不要在
touchstart就preventDefault,会导致 click 失效;建议在判断出手势意图(如位移 > 10px)后再阻止
真正难的从来不是写对 touch-action 值,而是在不同系统、不同 WebView 版本里确认它有没有被解析、有没有被父级覆盖、有没有和 overflow 或 transform 冲突。上线前务必在 iOS Safari、Chrome Android、微信内置浏览器里实机点划测试,截图看 devtools 的 computed 样式里 touch-action 是否显示为你设的值。


















