实现向下滚动隐藏、向上滚动显示的Sticky Header+固定进度条
解决思路与修正代码
我仔细看了你的代码,发现几个关键问题导致你想要的效果没实现,咱们一步步来修复:
核心问题分析
- 进度条被嵌套在Header内:你把
.scroll-progress-bar放在了<header>标签里,所以当Header被隐藏(添加nav-up类)时,进度条也会跟着被移出视口,这就违反了“进度条始终显示”的需求。 - Header隐藏的位置计算不合理:
nav-up类的top: -300px是固定值,如果Header高度变化,这个值就会失效,应该用负的Header高度来精准控制。 - 缺少进度条宽度更新逻辑:你的代码里没有计算滚动进度来更新进度条的宽度,所以进度条根本不会动。
- Header的类结构有问题:你把
nav-down加在了Header内部的div上,而不是直接加在<header>标签本身,导致滚动逻辑无法正确切换类。
修正后的完整代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- Header独立出来,进度条作为同级元素 --> <header class="nav-down"> </header> <div class="scroll-progress-bar"></div> <!-- 测试内容 --> <div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div>
CSS
body { padding-top: 30px; /* 对应Header的高度,避免内容被遮挡 */ overflow-x: hidden; margin: 0; /* 清除默认边距 */ } header { position: fixed; top: 0; transition: top 0.3s ease-in-out; /* 调整过渡时间更流畅 */ width: 100%; background: blue; height: 30px; z-index: 10; /* 确保Header在进度条上方 */ } .scroll-progress-bar { position: fixed; top: 30px; /* 刚好在Header下方,和Header高度一致 */ left: 0; height: 3px; width: 0; background: green; z-index: 5; /* 层级低于Header,高于页面内容 */ transition: width 0.1s ease; /* 进度条宽度变化的过渡效果 */ } .nav-up { top: -30px; /* 精准隐藏Header,值为负的Header高度 */ }
JavaScript
// Hide Header on scroll down, Show Header on scroll up var didScroll; var lastScrollTop = 0; var delta = 5; var navbarHeight = $('header').outerHeight(); $(window).scroll(function(event){ didScroll = true; // 滚动时同时更新进度条 updateScrollProgress(); }); setInterval(function() { if (didScroll) { hasScrolled(); didScroll = false; } }, 250); function hasScrolled() { var st = $(this).scrollTop(); // 忽略小幅度滚动 if(Math.abs(lastScrollTop - st) <= delta) return; // 向下滚动且超过Header高度时隐藏Header if (st > lastScrollTop && st > navbarHeight){ $('header').removeClass('nav-down').addClass('nav-up'); } else { // 向上滚动时显示Header,除非已经到页面底部 if(st + $(window).height() < $(document).height()) { $('header').removeClass('nav-up').addClass('nav-down'); } } lastScrollTop = st; } // 更新滚动进度条宽度的函数 function updateScrollProgress() { var windowHeight = $(window).height(); var documentHeight = $(document).height(); var scrollTop = $(window).scrollTop(); // 计算滚动百分比 var scrollPercent = (scrollTop / (documentHeight - windowHeight)) * 100; // 设置进度条宽度 $('.scroll-progress-bar').css('width', scrollPercent + '%'); }
关键改动说明
- 结构调整:把进度条从Header中移出,作为独立的页面元素,这样Header隐藏时进度条不受影响。
- 定位优化:进度条的
top值设置为Header的高度(30px),确保它始终在Header原本的下方位置;当Header隐藏时,进度条就会停留在页面顶部。 - 精准隐藏Header:
nav-up类的top值改为-30px,和Header高度一致,避免过度偏移。 - 添加进度条逻辑:新增
updateScrollProgress()函数,根据滚动位置计算百分比,动态更新进度条宽度。 - 层级调整:通过
z-index确保Header在进度条上方,进度条在页面内容上方,避免遮挡问题。
这样调整后,就能实现你想要的效果:向下滚动时Header隐藏,向上滚动时Header显示,进度条始终固定在页面顶部(Header隐藏时)或Header下方(Header显示时),滚动进度实时更新。
内容的提问来源于stack exchange,提问作者kp123
相关产品推荐
相关产品推荐

