【2024 更新】纯 CSS 方法实现
在 CSS 中,传统的动画是通过 @keyframes 规则定义的,然后使用 animation 属性来控制动画的播放。这些动画通常在时间线上运行,与用户滚动页面无关。而在 Chrome 115 或更高版本的浏览器中,支持了新的 CSS 属性 animation-timeline: scroll();。这个属性允许你将动画与滚动事件关联起来,创建滚动驱动的动画效果,使得我们可以通过纯 CSS 方法实现页面滚动条。
<style>
.container {
max-width: 800px;
margin: 0 auto;
padding: clamp(1rem, 2vw, 5rem);
}
.progress {
height: 5px;
background: #33a6b8;
border-radius:5px;
position: fixed;
top: 0;
left: 0;
width: 100%;
transform-origin: 0 50%;
animation: scaleProgress auto linear;
animation-timeline: scroll(root);
}
@keyframes scaleProgress {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
</style>
<div class="progress"></div>
scrollHeight , scrollTop 与 clientHeight

完整网页图片
这是一个完整的网页,其中红框的区域(浏览器窗口中可见的区域)的高度是 clientHeight。红框的区域到顶部的距离是 scrollTop,而整个网页的高度是 scrollHeight。了解了这些之后,可以计算出当前滚动条位置占整个页面高度的比例:scrollTop / (scrollHeight - clientHeight)。这个比例表示用户已经浏览了页面的多少百分比。
进度条
这里使用 MDUI 的进度条,不过需要在样式中加一个 position: fixed 使它悬浮在页面的顶部。
添加代码
在页面引入相关的代码之后,添加一个 JS 并且按照第一部分的方法获取阅读进度:
const TOTAL_HEIGHT = document.documentElement.scrollHeight;
const VIEWPORT_HEIGHT = document.documentElement.clientHeight;
const PROGRESS_BAR_ID = "进度条 ID";
const progressBar = document.getElementById(PROGRESS_BAR_ID);
window.onscroll = function() {
let scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
let scrollPercent = (scrollTop / (TOTAL_HEIGHT - VIEWPORT_HEIGHT)) * 100;
progressBar.style.width = `${scrollPercent}%`;
// 如果页面内容不足以显示进度条,则隐藏进度条
if (TOTAL_HEIGHT <= VIEWPORT_HEIGHT) {
progressBar.style.display = 'none';
} else {
progressBar.style.display = 'block';
}
}
window.addEventListener('scroll', (event) => {
requestAnimationFrame(() => {
let scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
let scrollPercent = (scrollTop / (TOTAL_HEIGHT - VIEWPORT_HEIGHT)) * 100;
progressBar.style.width = `${scrollPercent}%`;
});
});
这样就可以有一个阅读进度条了。