滚动时导航栏自动隐藏需用JavaScript监听scroll事件并记录lastScrollY,向下滚动超阈值时添加hidden类通过transform隐藏,向上滚动时移除;须用requestAnimationFrame节流、初始lastScrollY设为-1防误判,并适配非window滚动场景。

滚动时导航栏自动隐藏的 CSS + JS 实现
直接用 position: sticky 无法实现“滑动隐藏”,它只支持固定吸附,不响应滚动方向。真正能判断向上/向下滚动并隐藏导航栏的,必须靠 JavaScript 监听 scroll 事件 + 记录上一次 scrollTop 值。
核心逻辑很简单:当页面向下滚动且当前滚动位置比上次更大时,隐藏导航栏;向上滚动时再显示。但容易忽略滚动抖动、节流、初始状态等问题。
- 给
<nav>添加 class"navbar",方便样式和 JS 选择 - 初始状态设为
transform: translateY(0),后续通过修改transform隐藏(比display: none更利于动画和布局稳定) - 用
requestAnimationFrame节流,避免高频触发导致卡顿 - 记录
lastScrollY,每次 scroll 时对比:若window.scrollY > lastScrollY且超出阈值(比如 10px),则添加"hidden"class
示例关键 JS 片段:
let lastScrollY = 0;
const navbar = document.querySelector('.navbar');
window.addEventListener('scroll', () => {
const currentScrollY = window.scrollY;
if (currentScrollY > lastScrollY && currentScrollY > 10) {
navbar.classList.add('hidden');
} else if (currentScrollY < lastScrollY) {
navbar.classList.remove('hidden');
}
lastScrollY = currentScrollY;
});
隐藏动画必须用 transform 而不是 top/margin
用 top 或 margin-top 控制隐藏会导致重排(reflow),动画卡顿,且可能破坏原有布局流。正确做法是只改 transform: translateY(),它走 GPU 加速,不触发重排。
立即学习“前端免费学习笔记(深入)”;
CSS 示例:
.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
transition: transform 0.3s ease-out;
}
.navbar.hidden {
transform: translateY(-100%);
}
-
transition必须写在非.hidden状态上,否则首次隐藏无动画 -
translateY(-100%)表示完全移出视口顶部,数值不能写成px绝对值,否则在不同高度导航栏下会失效 - 如果导航栏有
box-shadow或背景渐变,隐藏时建议同步加opacity: 0避免边缘残留
移动端 touchstart/touchmove 会干扰 scroll 判断
在 iOS Safari 和部分安卓浏览器中,快速滑动时 scroll 事件可能滞后或丢失,仅靠它判断滚动方向不可靠。必须补充 touch 事件做兜底。
- 监听
touchstart记录起始pageY - 在
touchmove中实时对比移动方向,临时覆盖lastScrollY判断逻辑 - touch 结束后(
touchend)恢复 scroll 判断,避免长按误触发 - 注意:不要同时绑定
scroll和touchmove做重复操作,否则动画会跳变
兼容性与边界情况处理
这个功能在桌面端基本稳定,但在 iOS 上有三个典型坑:
- iOS Safari 滚动惯性结束时,
scroll事件可能不触发最后一次scrollY回弹,导致导航栏卡在隐藏状态 —— 解决方案:加setTimeout在touchend后 300ms 强制检查并恢复显示 - 页面底部内容不足一屏时,滚动条不可见,
window.scrollY始终为 0,整个逻辑失效 —— 应提前判断document.body.scrollHeight > window.innerHeight - 使用
overflow: hidden或第三方滚动库(如 iScroll)时,原生window.scrollY不更新 —— 必须改用目标容器的scrollTop
最易被忽略的是:没考虑用户手动拖拽滚动条到顶部又快速向下滚的情况,此时 lastScrollY 初始值应设为 -1 而非 0,避免首次滚动就误判隐藏。



















