<p>顶部进度条必须用 JavaScript 动态计算滚动比例:取 Math.max(document.body.scrollTop, document.documentElement.scrollTop) 为真实 scrollTop,再代入 (scrollTop / (document.documentElement.scrollHeight - window.innerHeight)) * 100 得准确百分比,配合 style.width 实时更新;position: sticky 无法替代,纯 CSS 无解。</p>

用 window.onscroll 监听滚动并更新 width 最直接
页面滚动时动态更新顶部进度条宽度,核心就是实时读取 scrollTop 和 scrollHeight,算出滚动比例。别用 requestAnimationFrame 过度优化——简单页面用原生 onscroll 完全够用,也更易调试。
常见错误是把 document.body.scrollTop 当成唯一来源,其实得优先看 document.documentElement.scrollTop(尤其在 Chrome/Firefox 的标准模式下),否则进度条可能卡在 0% 不动。
- 始终用
Math.max(document.body.scrollTop, document.documentElement.scrollTop)取真实滚动距离 -
const progress = (scrollTop / (document.documentElement.scrollHeight - window.innerHeight)) * 100才是准确百分比 - 记得给进度条
div设置position: fixed; top: 0; left: 0; height: 2px;,width用内联样式或style.width动态设
为什么不能只靠 CSS position: sticky
position: sticky 无法实现“随滚动线性增长的宽度”,它只是让元素在某个临界点粘住,不响应滚动比例。想做进度条,必须 JS 驱动 —— 没有纯 CSS 替代方案。
有人试过用 transform: scaleX() 配合 getBoundingClientRect(),但计算复杂、触发重排频繁,反而不如直接改 width 稳定。
立即学习“前端免费学习笔记(深入)”;
-
sticky是定位行为,不是状态映射,它不提供滚动进度数据 - 所有“伪进度条”(比如用
linear-gradient+background-position)都绕不开 JS 控制偏移量 - 移动端 iOS Safari 对
scrollHeight计算有小偏差,建议加Math.min(progress, 100)防止超 100%
性能关键:节流不是必须,但避免重绘扩散
每次滚动都设 style.width 本身开销极小,真正拖慢的是连带触发的布局重排(layout)—— 尤其当你同时操作其他 DOM 属性或读取 offsetHeight 之类。
不要一上来就套 lodash.throttle,先确认是否真有卡顿。多数情况只需保证:只改 width,不读写其他布局相关属性,就能跑满 60fps。
- 用
element.style.width = progress + '%',别用classList切换预设 class(会触发样式重计算) - 避免在滚动回调里调用
getComputedStyle()或访问offsetTop等触发同步 layout 的 API - 如果页面有大量监听器,检查是否重复绑定
window.onscroll,导致同一事件被多次处理
兼容性注意:IE11 下 document.documentElement.scrollTop 可能为 0
IE11 在怪异模式(quirks mode)下,document.body.scrollTop 才有效;标准模式下则依赖 document.documentElement.scrollTop。但 IE11 已基本退出主流,除非明确要支持,否则不用额外降级。
更现实的问题是 Safari 移动端:scrollHeight 在页面内容未完全加载时可能不准,导致初始进度跳变。解决方案很简单——延迟到 DOMContentLoaded 后再初始化进度条逻辑。
- 初始化时加个
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initBar) } - 别在
head里就执行滚动监听,DOM 没挂载完会报错或返回 0 - 如果用了第三方库(如
smooth-scroll),它们可能劫持原生滚动,需查文档看是否暴露了进度钩子
滚动进度条看着简单,真正上线时最容易翻车的是 scrollHeight 计算时机和跨浏览器 scrollTop 来源混用——这两个点不盯紧,进度条要么不动、要么飙到 200%。


















