LoginSignup
0
0

スクロールに合わせて、ヘッダーの表示/非表示を制御する

Posted at

はじめに

表題通り、スクロールに合わせて表示、非表示を制御するコードを記載します。

成果物

仕組み

現在のスクロール位置、スクロール後の位置を取得し比較。比較の結果、スクロールアップかダウンを検知し、それに合わせてCSSを変更する処理。聞いてみれば意外と単純。。。

ソースコード

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>スクロールアップ</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>  
    <header id="header">ヘッダー</header>
    <main>
        <p>要素1</p>
        <p>要素2</p>
        <p>要素3</p>
        <p>要素4</p>
        <p>要素5</p>
        <p>要素6</p>
        <p>要素7</p>
        <p>要素8</p>
        <p>要素9</p>
        <p>要素10</p>
        <p>要素11</p>
        <p>要素12</p>
        <p>要素13</p>
        <p>要素14</p>
        <p>要素15</p>
        <p>要素16</p>
        <p>要素17</p>
        <p>要素18</p>
        <p>要素19</p>
        <p>要素20</p>
        <p>要素21</p>
        <p>要素22</p>
        <p>要素23</p>
        <p>要素24</p>
        <p>要素25</p>
    </main>
    <footer id="footer">ヘッダー</footer>
    <script src="script.js"></script>
</body>
</html>

styles.css
body {
    padding: 0;
    margin: 0;
}
header {
    display: flex; /* Flexコンテナを使用して水平・垂直方向に中央揃えにする */
    justify-content: center; /* 水平方向の中央揃え */
    align-items: center; /* 垂直方向の中央揃え */
    position: fixed;
    background: #ddd;
    background-color: antiquewhite;
    padding: 0;
    width: 100%;
    height: 90px;
    margin-top: 0px;
    transition: margin 100ms;
}
footer {
    display: none;
    background: #333;
    color: #fff;
    padding: 20px;
    text-align: center;
}

.scroll-down header {
    margin-top: -90px;
}
.scroll-up header {
    margin-top: 0px;
}


main {
    height: 200vh;
    background: #ccc;
    padding: 120px 30px;
}
script.js
// スクロール前のスクロール位置を保持する変数
let lastScrollPosition = window.scrollY;
// 現在のスクロール位置を保持する変数
let currentScrollPosition = 0;
// requestAnimationFrameの実行中かどうかを保持する変数。過剰な発火を防ぐ
let ticking = false;

function scrollUpDown(scrollPos, lastScrollPos) {
    // 現在のスクロール位置が前回のスクロール位置よりも大きい場合、スクロールダウンを検知
    if (scrollPos > lastScrollPos) {
        // スクロールダウン
        document.body.classList.remove('scroll-up');
        document.body.classList.add('scroll-down');
        console.log('SCROLLING DOWN: scrollPos: ',scrollPos,"lastScrollPos", lastScrollPos)
    } else {
        document.body.classList.add('scroll-up');
        document.body.classList.remove('scroll-down');
        console.log('SCROLLING UP: scrollPos: ',scrollPos,"lastScrollPos", lastScrollPos)
    }
}

// ウインドウのスクロールイベントを監視
window.addEventListener('scroll', function (e) {
    // スクロールイベントが発火したら、現在のスクロール位置を保持する
    currentScrollPosition = window.scrollY;

    //スクロールイベントの過剰な実行を制御します。
    if (!ticking) {
        // requestAnimationFrameを使って、scrollUpDown関数を実行する
        window.requestAnimationFrame(function () {
            scrollUpDown(currentScrollPosition, lastScrollPosition);
            lastScrollPosition = currentScrollPosition;
            ticking = false;
        });

        ticking = true;
    }
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0