获取页面滚动进度的准确方法是用window.scrollY除以document.documentElement.scrollHeight减去window.innerHeight,并通过Math.min(1, Math.max(0, ...))限定在[0,1]区间,同时需处理scrollHeight≤innerHeight的边界情况。

要获取页面滚动进度,核心是计算当前滚动位置占整个可滚动高度的百分比。这个值通常在 0%(顶部)到 100%(底部)之间变化,适用于进度条、视差效果或懒加载等场景。
基础公式:滚动进度 = 当前滚动距离 / 可滚动总高度
关键不是用 window.scrollY 除以 document.body.scrollHeight,因为
-
当前滚动位置:用
window.pageYOffset或window.scrollY(两者等价,推荐scrollY) -
可滚动总高度:用
document.documentElement.scrollHeight - window.innerHeight(减去视口高度,得到实际可滚动距离) - 进度值(0–1):`scrollY / (document.documentElement.scrollHeight - window.innerHeight)`
兼容性处理:避免除零和边界异常
当页面内容不足一屏时,scrollHeight - innerHeight 可能 ≤ 0,直接除会出错或得 Infinity。需加保护逻辑:
- 先判断
scrollHeight ≤ innerHeight,此时进度恒为 0 - 否则再计算,结果用
Math.min(1, Math.max(0, ...))限定在 [0, 1] 区间 - 示例代码:
const progress = document.documentElement.scrollHeight <= window.innerHeight<br> ? 0<br> : Math.min(1, Math.max(0, window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)));
实时监听滚动并更新进度
用 scroll 事件监听,但注意性能——建议节流或使用 requestAnimationFrame:
立即学习“Java免费学习笔记(深入)”;
- 简单节流(每 16ms 最多执行一次):
let ticking = false;<br>function updateProgress() {<br> if (!ticking) {<br> requestAnimationFrame(() => {<br> // 计算并应用 progress<br> ticking = false;<br> });<br> ticking = true;<br> }<br>}<br>window.addEventListener('scroll', updateProgress); - 若只需整数百分比,可用
Math.round(progress * 100)转为 0–100 的整数
常见用途与注意事项
滚动进度常用于视觉反馈,比如固定顶部进度条、文字透明度渐变、元素入场动画等。
- 不要依赖
body.scrollTop—— 在现代浏览器中它常为 0,应始终用document.documentElement或window级属性 - 移动端需注意:iOS Safari 中
scrollY在某些 meta 设置下可能不准,确保<meta name="viewport" content="width=device-width, initial-scale=1"> - 若页面有动态内容加载(如无限滚动),记得在新内容插入后重新评估
scrollHeight,必要时触发一次进度更新


















