###画面のスクロールに応じて変化するスティッキーなヘッダーの作り方
✴︎要はこれを自作で作る方法
####HTML,CSS
サンプルとして、以下の様なヘッダーとブロックを持つdiv要素の群があるとします。
sample.html
<!DOCTYPE HTML>
<html>
<style>
body {
margin: unset;
}
div.block{
height: 2600px;
width: 100%;
}
div.block.one{
background-color: #C1A1FF;
}
div.block.two{
background-color: #9892E8;
}
div.block.three{
background-color: #AEBEFF;
}
div.block.four{
background-color: #92BAE8;
}
div.header{
font-size: 1.5em;
text-align: center;
}
div.header.one{
background-color: #A269FF;
}
div.header.two{
background-color: #6D5FE8;
}
div.header.three{
background-color: #768DFF;
}
div.header.four{
background-color: #5797EB;
}
</style>
<body >
<div class='block one'>
<div class="header one">
This is Header Number one.
</div>
</div>
<div class='block two'>
<div class="header two">
This is Header Number two.
</div>
</div>
<div class='block three'>
<div class="header three">
This is Header Number three.
</div>
</div>
<div class='block four'>
<div class="header four">
This is Header Number four.
</div>
</div>
</body>
</html>
ヘッダーがスティッキーじゃないですね。
動的にスティッキーになる様にJSを足しましょう。
####JS
sample.js
let activateStickyHeader = function() {
let blocks = document.getElementsByClassName('block');
let targetHeight = [];
for (let i = 0; i < blocks.length; i++) {
targetHeight.push(blocks[i].getBoundingClientRect().top + window.pageYOffset);
}
let headers = document.getElementsByClassName('header')
document.addEventListener('scroll', function(){
let y = window.pageYOffset ;
for (let key in targetHeight) {
if( y >= targetHeight[key]){
headers[key].style.position = 'sticky';
headers[key].style.top = '0';
} else {
headers[key].style.position = '';
headers[key].style.top = '';
}
}
})
};
document.addEventListener("DOMContentLoaded", function(){
activateStickyHeader()
}, false);
#####JS処理で何をやっているか。
document.getElementsByClassName('block')
でそれぞれのブロックの要素を取得し、
blocks[i].getBoundingClientRect().top + window.pageYOffset
これで各ブロック要素の画面上の位置(スクロール量を未考慮)+ページトップを0とした時の画面を開いた時のスクロール量
= ページ内の位置 となります。
これらを配列に入れ、ウインドウのスクロール位置が各ブロックのページ内の位置に到達した際に、
対応するヘッダーのスタイルを書き換えてスティッキーなヘッダーにしています。
うん。良い感じですね!