应使用 getBoundingClientRect().top 判断滚动阈值,而非直接比较 window.scrollY 与固定像素值;因 banner、加载延迟、缩放或 sticky 布局会导致 window.scrollY 提前超限,引发导航栏变色错位。

滚动阈值判断用 getBoundingClientRect().top,别硬写 window.scrollY > 100
直接比 window.scrollY 和固定像素值(比如 100)是最常见错误。页面有 banner、加载延迟、缩放或 sticky 布局时,window.scrollY 可能早于导航栏真正贴顶就超过阈值,导致变色提前或错位。
- 用
document.querySelector('.navbar').getBoundingClientRect().top 判断导航栏是否已滚动出视口顶部——这是它“开始遮挡内容”的真实信号 - 更稳妥加缓冲:用
<= -10,避免临界点反复触发 class 切换 - 如果导航栏用了
.fixed-top或.sticky-top,getBoundingClientRect().top仍有效;但若父容器设了overflow: hidden,sticky 失效,需先修复布局
background-color 必须用 rgba() 起始,transparent 无法过渡
写 background-color: transparent 看似合理,但 CSS transition 对 transparent → rgba() 不插值,结果是“啪”一下跳变,不是渐变。
- 初始状态必须设为
background-color: rgba(255, 255, 255, 0)(白底全透)或rgba(0, 0, 0, 0)(黑底全透) - 滚动后切换的类里写
background-color: rgba(255, 255, 255, 0.95),alpha 值从 0 → 0.95 才能平滑过渡 - 务必同时加
background-image: none !important,否则 Bootstrap 5 默认的linear-gradient()会盖在 rgba 上,让透明看起来发灰
transition 要写在默认状态,且只限定属性
很多人把 transition: background-color 0.3s 只写在 .navbar-scrolled 类里,结果没效果——transition 必须定义在「始终存在」的默认规则中,浏览器才能感知变化。
- 在
.navbar或.navbar-light的原始样式里写:transition: background-color 0.3s ease, backdrop-filter 0.3s ease - 别写
transition: all 0.3s,它会强行过渡 height、opacity 等无关属性,拖慢渲染 - 如果用了
backdrop-filter: blur(10px),记得加-webkit-backdrop-filter: blur(10px)兼容 Safari
移动端要防 body 不滚动、requestAnimationFrame 节流不能少
iOS Safari 和部分安卓 WebView 下,window.scrollY 经常恒为 0,因为实际滚动的是 <main> 或 .container,而不是 document.body。
- 验证方式:控制台输
window.scrollY,滚动看是否变化;不变就改监听document.documentElement.scrollTop或目标容器的scrollTop - scroll 事件每秒触发几十次,不节流会导致频繁 DOM 查询和 class 切换,低端机明显卡顿
- 用
requestAnimationFrame包裹判断逻辑,比setTimeout更精准,且不滞后:“滚动停稳前最后一帧才执行”
getBoundingClientRect() 读取时机、rgba() 起始值类型、以及移动端滚动源错位这三点——它们不出现在控制台报错里,却让效果要么不动、要么闪、要么提前触发。


















