スクロールに追随する複数のヘッダーの作り方


###画面のスクロールに応じて変化するスティッキーなヘッダーの作り方
✴︎要は[これ](https://materializecss.com/pushpin-demo.html)を自作で作る方法

####HTML,CSS
サンプルとして、以下の様なヘッダーとブロックを持つdiv要素の群があるとします。


```html: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>
```

まあ、
こんな感じです。
![画面収録-2020-05-11-23.26.36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180253/9d6ab24b-d466-5dc5-d359-83ff90e034b7.gif)


ヘッダーがスティッキーじゃないですね。
動的にスティッキーになる様にJSを足しましょう。

####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とした時の画面を開いた時のスクロール量
 = ページ内の位置 となります。

これらを配列に入れ、ウインドウのスクロール位置が各ブロックのページ内の位置に到達した際に、
対応するヘッダーのスタイルを書き換えてスティッキーなヘッダーにしています。

sample.jsをsample.htmlに入れてみると
![画面収録-2020-05-11-23.27.59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180253/e02ba3cb-22c1-19d5-16f0-d023b256c2ee.gif)

うん。良い感じですね！