【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}%`;
});
});
これで読書進捗バーが表示されます。