記事全体の読んだ分量を示すバーをつくる
- 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