記事全体の読んだ分量を示すバーをつくる
- 2019.03.21
- javascript+css つくったもの
- 脱jQuery
最近メディアサイトなどでよく見かけて、ユーザービリティ的にいいなあと思ったのでつくってみました。
まずはデモをご確認ください。
考え方
記事部分の高さを取得。
それを1000分の1ずつにわける。
スクロール量が記事の高さの1000分の1進むごとに、バーが0.1%ずつ進んでいく。
コード解説
htmlとcss
<div id="meter">
<div id="meterInner"></div>
</div>
<div id="contents">
コンテンツが入ります。<br>
コンテンツが入ります。
</div>
#meter {
height: 3px;
width: 100%;
transition: .5s;
position: fixed;
}
#meterInner {
background-color: black;
width: 100%;
height: 3px;
position: absolute;
left: -100%;
}
#contents {
background-color: lightgray;
}
#meter は、記事全体の分量を示す部分。高さ3px横幅いっぱいのバーとしました。
transition: .5s; を入れて、バーの動きをなめらかにするようにしています。
位置はfixedにしました。
#meterInner は、読んだ分量を示す色付きのバー。色を黒にしています。
あらかじめ left: -100%; としておきます。
読んだ分量に応じてこの #meterInner の位置を右へずらしていくことでバーを進ませます。
#contents は記事部分です。
javascript
var meter = document.getElementById('meterInner'); // 読んだ分量を示すバー
var contents = document.getElementById('contents'); // 記事部分を取得
var contentsHeight = contents.clientHeight - window.innerHeight; // 記事部分の高さ
var windowY = window.pageYOffset; // スクロール位置を取得
var contentsRect = contents.getBoundingClientRect(); // 記事が始まる位置
var contentsY = contentsRect.top + windowY; // 記事が始まる位置
var volume = contentsY; // 記事の分量を入れるための変数。初期値は記事の開始位置
var volumes = []; // 記事の分量を入れるための配列
for (var i = 0; i < 1000; i++) { // 1000回ループ
volumes.push(volume); // 配列volumesにvolumeを入れる。初期値は記事の開始位置
volume += contentsHeight / 1000; // 記事の高さを1000分の1したものをvolumeにプラス。
}
// スクロールすると
window.addEventListener('scroll', function() {
// スクロール位置を取得
windowY = window.pageYOffset;
for (var i = 0; i < volumes.length; i++) {
// スクロール位置が記事分量の1000分の1に達するごとに、分量を示すバーを0.1%ずつ右に移動させる
if(windowY > volumes[i]) {
meter.style.transform = 'translate('+ i / 10 +'%, 0)';
}
}
});
記事部分の高さを取得。それを1000分の1にして配列に入れる。
配列の1番目は記事の開始位置とする。
スクロールがあるたびに、記事部分の高さを1000分の1ずつにした配列それぞれに達したか調べて、達するごとに
css の transform の translate で0.1%ずつ右へずらしていきます。
使い方
それぞれコピペしてもらえれば動くと思います。
任意でバーの色をcssで変えてもらったり、記事本文にあたる#contentsのidやclass名に応じてjsのソースも変更してもらえればOKです!
-
前の記事
javascriptとcssで作るカテゴリーソート機能 2019.02.23
-
次の記事
振ると色が変わるスマホ用コンテンツをつくってみた 2019.03.21