body { overflow: hidden } 在 ios 上无效,因 safari 无视该样式,需同时控制 html/body 样式、dom 位置(如 html position: fixed + top 偏移)及 touchmove 事件拦截,并精确还原 scrolly。

body { overflow: hidden } 在 iOS 上根本锁不住滚动
直接给 body 加 overflow: hidden 是最常见也最容易失效的做法。iOS Safari 会无视它——地址栏收起/展开、软键盘弹出、甚至滚动惯性,都会强行触发底层页面滚动。这不是 bug,是 WebKit 的行为特性:它把 body 当作“可滚动容器”但不完全尊重其 overflow 设置。
真正起作用的是同时控制 html 和 body:
- 记录当前
window.scrollY值 - 给
html加style="position: fixed; top: -${scrollTop}px; width: 100%",物理位移锁定视口 - 再设
body { overflow: hidden }防止键盘唤起时内容上顶 - 关闭时恢复
html.style.position,并调用window.scrollTo(0, scrollTop)
overscroll-behavior 没生效,大概率设错了元素
overscroll-behavior: none 只对**实际可滚动的容器**生效,不是弹窗 wrapper,而是它内部那个带 overflow-y: auto 的内容区(比如 .popup__content)。设在 .popup(position: fixed 容器)上完全无效,因为该元素本身不可滚动。
必须满足三个条件:
- 目标元素有明确高度(如
max-height: 80vh) - 设置了
overflow-y: auto或scroll -
overscroll-behavior写在该元素上,不是父级遮罩层
旧版 Safari(iOS
touchmove 事件拦截太粗暴,连弹窗内滚动都废了
在 document 上监听 touchmove 并无差别调用 event.preventDefault(),等于禁掉所有触摸滚动——弹窗里的轮播、长列表、输入框光标拖动全失效。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
安全做法是精准拦截:
- 监听
touchmove时,用event.target.closest('.popup')判断是否在弹窗内 - 不在弹窗内才
preventDefault() - 注册时必须加
{ passive: false },否则 Safari 忽略阻止 - 弹窗关闭后务必
removeEventListener,否则内存泄漏
iOS 键盘一弹,背景就闪一下或跳到顶部
这是 WebKit 的硬伤:键盘唤起时,浏览器强制把聚焦元素滚进可视区,哪怕你已经用 JS 锁死了 html。CSS 和常规滚动锁定挡不住这个行为。
缓解手段有限但管用:
- 给弹窗内
<input>或<textarea></textarea>加scrollIntoView({ block: 'nearest' }) - 键盘弹出瞬间,用
setTimeout(() => window.scrollTo(0, scrollTop), 100)强制回位(延迟值在 iOS 下很关键) - 若弹窗含表单,考虑用
position: fixed+top: env(safe-area-inset-top)把输入框钉在键盘上方
滚动穿透不是单一问题,而是 iOS 滚动机制、事件冒泡、CSS 渲染层和键盘行为四者叠加的结果。任何只靠一个 CSS 属性或一行 JS 的方案,都容易在某个环节漏掉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










