JavaScript でスクロール値を取得して画面に Youtube っぽいバーを表示しよう

phi phi on javascript

こちら

の発展です.

思いついたので作ってみました. 画面がちょっとだけ Youtube っぽくなります.

Runstant Demo

とりあえずデモです. スクロールすると下のバーが Youtube のように赤くなるのが 分かるかと思います.

Code

html

<body>  
  <h1>JavaScript で要素のスクロール値を取得して背景色に反映させてみよう</h1>
  <h2>スクロールしてね♪</h2>
  <div class='pad'></div>
  <footer>footer</footer>
  <br />
  <br />
</body>  

css

.bar {
  position: fixed;
  width: 0%;
  height: 8px;
  left: 0px;
  bottom: 0px;
}

.bar:before, .bar:after {
  content: '';
  display: block;
  position: absolute;
  height: inherit;
}

.bar:before {
  width: 100vw !important;
  background-color: hsl(0, 0%, 55%);
}

.bar:after {
  width: 100%;
  background-color: hsl(0, 80%, 55%);
}

javascript

Object.defineProperty(HTMLElement.prototype, 'scrollTopRate', {  
  get: function() {
    var maxScrollValue = this.scrollHeight - this.offsetHeight;
    return (this.scrollTop/maxScrollValue);
  }
});

window.onload = function() {  
  addYoutubeBar();
};

var addYoutubeBar = function() {  
  // バー用の要素を生成
  var bar = document.createElement('div');
  bar.classList.add('bar');
  document.body.appendChild(bar);

  window.onscroll = function(e) {
    // スクロールしている要素を取得
    var element = document.scrollingElement;
    // スクロールレートを取得
    var rate = element.scrollTopRate;
    // bar の幅に反映
    bar.style.width = (rate*100) + '%';
  };
};

Tips

scroll 値を rate として取得する方法

defineProperty で定義しています.

Object.defineProperty(HTMLElement.prototype, 'scrollTopRate', {  
  get: function() {
    var maxScrollValue = this.scrollHeight - this.offsetHeight;
    return (this.scrollTop/maxScrollValue);
  }
});

詳しくはこちらを -> HTMLElement を拡張して手軽に scroll rate を取得できるようにしよう | phiary

:after, :before 擬似要素の活用

擬似要素を活用することで, HTML 側をシンプルに保ちつつ複雑な表現をすることができます.

今回は, .bar:before, :after 擬似要素でそれぞれ バーの背景, バーゲージを表現しています.

詳しくはこちらを -> 表現の幅が広がる!!? CSS3 で追加された ::before, ::after 擬似要素の使い方 | phiary

ビューポートの割合に応じた幅の指定

:before の方は, width: 100vw という形で vw(viewport width) を指定することで 親要素の幅に左右されない形で幅指定してます.

一方 :after の方は width:100% としているので, .bar の幅に応じて伸縮します.

.bar:before {
  width: 100vw !important;
  background-color: hsl(0, 0%, 55%);
}

.bar:after {
  width: 100%;
  background-color: hsl(0, 80%, 55%);
}

こうすることで .bar の幅を javascript で変更するだけで, シンプルなバーを表現できます.

// スクロールレートを取得
var rate = element.scrollTopRate;  
// bar の幅に反映
bar.style.width = (rate*100) + '%';  

vw, vh についてより知りたいという方はこちらを ->
[CSS]ビューポート(vw, vh)とパーセント(%)、レスポンシブに適した単位の賢い使い分け方法 | コリス