overscroll-behavior加了无效,因其仅对真实可滚动且触顶/底的子元素生效;须设在.modal__content等含overflow-y:auto和明确高度的子容器上,而非.modal wrapper,且ios 16.4以下不支持。

直接给滑动容器加 overscroll-behavior: contain 通常无效——它只在子元素真实可滚动且触顶/底时起作用,而多数冲突源于滚动源没识别准、或容器根本不可滚动。
为什么 overscroll-behavior 加了也没用
这个属性不是“全局禁穿透”,而是「切断滚动链」的开关,必须满足三个硬条件才生效:
- 目标元素本身要可滚动:得有
overflow-y: auto(或scroll)且内容实际超出其高度 - 不能设在 wrapper 上:比如
.modal是position: fixed容器,它自己不可滚动,overscroll-behavior直接被忽略 - 必须设在真正滚动的子区域上:如
.modal__content、.chat-list、.sidebar-menu - iOS 16.4 以下 Safari 完全不支持,写了也白写
touchmove 中该不该调 e.preventDefault()
无差别调用 e.preventDefault() 是最常见翻车点——它会同时锁死 textarea 输入、内部列表滚动、甚至双指缩放。正确做法是按需拦截:
- 只监听弹窗根节点(如
#popup),别绑document或body - 用
e.target.closest('.scrollable')判断当前触摸点是否落在可滚动区内部 - 不在可滚动区内才调
e.preventDefault();在就放行 - 务必加
{ passive: false },否则 iOS Safari 会忽略preventDefault
滚动位置保存和还原为什么总出错
用 position: fixed 锁 body 时,document.body.scrollTop 在 iOS Safari 中几乎总是 0,靠它还原必然失败:
- 必须优先读
window.pageYOffset(兼容性最好) - 还原时不能只设
top,还要同步document.documentElement.style.scrollBehavior = 'auto'防止跳顶 - 如果页面有 sticky header,
top偏移值得减去它的高度,否则视觉错位 - 键盘弹出后
window.innerHeight收缩,此时还原pageYOffset可能导致内容被遮挡——得监听focusin/focusout动态调整
真正难的不是加一行 CSS,而是确认哪个元素在滚动、它是否真的可滚动、以及用户手指到底碰到了什么区域。iOS 的滚动行为不按 DOM 层级走,而按渲染层合成树走,所以 devtools 里看着结构对,真机上照样失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











