应使用classList.toggle()切换CSS类并统一用rgba()定义背景色,transition须写在默认规则中,监听navbar.getBoundingClientRect().top≤1触发变色,用requestAnimationFrame节流且缓存DOM引用,同步控制.navbar-collapse背景。
直接用 classlist.toggle() 切换预设 css 类,配合 transition 控制背景色渐变,别在 scroll 回调里反复写 element.style.backgroundcolor——后者会破坏过渡、难维护、且在 safari 下常闪白。
为什么 background-color 过渡不生效
常见原因是起始值用了 transparent,而结束值是 rgba() 或十六进制色——浏览器无法在关键字和颜色值之间插值。必须统一用 rgba():初始状态设为 background-color: rgba(255, 255, 255, 0),滚动后切到 rgba(255, 255, 255, 0.95)。
另一个坑是只在 .navbar-scrolled 类里写 transition。必须把 transition: background-color 0.3s ease 写在默认的 .navbar 规则里,否则第一次切换时没有过渡效果。
-
background-image: linear-gradient(...)会盖住你设的background-color,务必加background-image: none - 如果用了
box-shadow,也得把它加进transition列表,否则阴影出现突兀 - 别写
transition: all 0.3s——它会拖慢不可动画属性(如display)的变更
滚动阈值该用 scrollY 还是 getBoundingClientRect()
用 window.scrollY > 50 看似简单,但一旦页面有首屏大图、响应式 padding 变化或 sticky fallback,这个固定值就失效。更稳的是监听导航栏自身位置:
取 document.querySelector('.navbar').getBoundingClientRect().top,当它 ≤ 0(即已贴顶),再触发变色。这样不受页面其他元素高度影响,适配 position: sticky 和 fixed-top。
- 移动端 Safari 对临界点敏感,建议留缓冲:
top ≤ 1而不是严格等于 0 - 首次加载后需手动调用一次判断逻辑,否则首页刷新后可能状态错乱
- 别在滚动回调里反复调用
getBoundingClientRect()——提前缓存元素引用,只在requestAnimationFrame里读一次
移动端 .navbar-collapse 背景为啥还是透明
因为 .navbar-collapse 是独立容器,不会继承 .navbar 的背景色或类名。你在 .navbar 上加了 .scrolled,但折叠菜单展开后仍透出底下内容。
解决方法不是给 .navbar-collapse 加 !important,而是同步控制它的背景:
- HTML 中显式给











