滚动指示器怎么实现才能实时反映页面滚动进度?
我最近在做个人作品集网站,想加个顶部的滚动进度条,就是那种随着页面往下滚,进度条从0%到100%慢慢变长的效果。试了用 window.scrollY 除以 document.body.scrollHeight - window.innerHeight 来算比例,但结果有时候超过1或者卡在某个值不动,尤其在移动端特别明显。
这是我的代码:
window.addEventListener('scroll', () => {
const scrollTop = window.scrollY;
const scrollHeight = document.body.scrollHeight - window.innerHeight;
const progress = (scrollTop / scrollHeight) * 100;
document.querySelector('.progress-bar').style.width = <code>${progress}%</code>;
});
是不是哪里没考虑到?比如 body 高度计算的问题?求指点!
document.body.scrollHeight有时候不太可靠,尤其是在移动端,建议改用document.documentElement.scrollHeight。另外,计算滚动比例时要注意除数不能为零,不然就会出现你遇到的问题。我改了一下你的代码:
顺便提醒下,滚动事件触发很频繁,最好加个防抖或者节流处理,不然在低端设备上可能会有性能问题。可以考虑用
requestAnimationFrame来优化。注意安全:记得对获取的元素做空值检查,防止找不到元素时报错。这在用户调整浏览器窗口大小时特别重要,因为可能会导致页面布局发生变化。
window.innerHeight的值。来一个改进版的解决方案,我通常会这么处理:
这里有几个关键改进点:
1. 用
requestAnimationFrame来节流滚动事件,比直接监听scroll性能好很多,特别是高频触发时2. 计算文档高度时用了
Math.max取多种计算方式的最大值,因为不同浏览器对scrollHeight的实现可能有差异3. 加了
Math.min和Math.max双重保险,确保进度值不会超出0-100范围4. 额外监听resize事件,因为移动端浏览器工具栏的显示/隐藏会改变视窗高度
5. 用
pageYOffset替代scrollY增强兼容性实际项目中我还会建议加个transition效果让进度条变化更平滑,比如:
移动端测试的时候特别要注意Safari,这货对文档高度的计算经常抽风,所以才要用那么多备选计算方式。