• HOME > 
  • JavaScript > 
  • JSで特定の位置までスクロールされたら要素を固定する方法【s...

JSで特定の位置までスクロールされたら要素を固定する方法【sticky風】

投稿日:

このページにはGoogleアドセンス広告とアフィリエイト広告が含まれています。

カテゴリー記事のアイキャッチ画像
広告
広告

CSSのstickyのような動きをJSで実装する

JavaScriptを使って、「ある要素がページ上部に当たるまでスクロールされたら、その位置でその要素を固定表示し続ける」という仕様を作る機会がありました。

CSSのstickyでも同様の仕様が作れますが、今回はstickyが使えない状況だったので素のJavaScriptのみ(jQueryも不要)で実装した方法を備忘録として残しておこうと思います。

下のGifが出来上がりのイメージです。固定したい要素がページの途中にあり、スクロールされてページ上部に達したらヘッダーとして固定し、再度上にスクロールされたら固定を解除するという仕様です。

スクロールされたら要素を固定する例

ソースコード

上のサンプルを作ったソースコードです(インラインで記述しているCSSはスクロールをわかりやすくするためのものなので実際は不要です)。

HTML

<div class="area">
    <div class="preElm" style="height:calc(50vh);background:#e9e9e9;"></div>
    <div class="fixedElm" style="width:100%;background:#999;color:#fff;font-weight:bold;padding:10px;">固定したい要素</div>
    <div class="dummyElm" style="height:calc(100vh + 250px);background:#d9d9d9;"></div>
    <div class="dummyElm" style="height:calc(100vh + 250px);background:#c9c9c9;"></div>
    <div class="dummyElm" style="height:calc(100vh + 250px);background:#b9b9b9;"></div>
    <div class="dummyElm" style="height:calc(100vh + 250px);background:#a9a9a9;"></div>
</div>

「固定させたい要素」と「固定させたい要素より上にある要素」を合わせた高さをスクロール量が上回ったら、position:fixedを指定したクラスを付与する(下回ったらクラスを削除する)という仕組みをJSで作ります。

JavaScript

function scrollFixed(){
    var fixedElm = document.querySelectorAll(".fixedElm");//固定させたい要素
    var preElm = document.querySelectorAll(".preElm");//固定させたい要素より上にある要素
    var hh = preElm[0].clientHeight + fixedElm[0].clientHeight;//固定させたい要素までの高さを取得
    window.addEventListener("scroll",function(){
        var scroll = window.pageYOffset;//スクロール量を取得
        if(hh < scroll){
            fixedElm[0].classList.add("myFixed");//固定するためのクラスを付与
        }else{
            fixedElm[0].classList.remove("myFixed");//クラスを削除
        }
    }); 
}
window.addEventListener("load",function(){
    console.log("load!");
    scrollFixed();
});

position:fixedで固定表示するスタイルを用意したら完成です(box-shadowで影を付けるかどうかはお好みで)。

CSS

.fixedElm.myFixed{
    box-shadow:0 2px 5px #333;
    position:fixed;
    top:0;
    left:0;
    z-index:999;
}

サイドバーを固定する場合

少し修正すればサイドバーの固定にも応用することができます。

スクロールされたらサイドバーを固定する例

上記サンプルのソースコードは以下の通りです(インラインで記述しているCSSはスクロールをわかりやすくするためのものなので実際は不要です)。

HTML

<header style="background:#333; color:#fff;padding:30px 10px;">ヘッダー</header>
<div class="area">
    <aside>
        <div class="fixedElm" style="width:100%;background:#999;color:#fff;font-weight:bold;padding:10px;">固定したい要素</div>
    </aside>
    <div class="mainElm">
        <div class="dummyElm" style="height:calc(100vh + 250px);background:#d9d9d9;"></div>
        <div class="dummyElm" style="height:calc(100vh + 250px);background:#c9c9c9;"></div>
        <div class="dummyElm" style="height:calc(100vh + 250px);background:#b9b9b9;"></div>
        <div class="dummyElm" style="height:calc(100vh + 250px);background:#a9a9a9;"></div>
    </div>
</div>

JavaScript

function scrollFixed(){
    var header = document.querySelectorAll("header");
    var fixedElm = document.querySelectorAll(".fixedElm");
    var mainElm = document.querySelectorAll(".mainElm");
    var hh = header[0].clientHeight + fixedElm[0].clientHeight;
    window.addEventListener("scroll",function(){
        var scroll = window.pageYOffset;
        //console.log(scroll);
        if(hh < scroll){
            fixedElm[0].classList.add("myFixed");
        }else{
            fixedElm[0].classList.remove("myFixed");
        }
    }); 
}
window.addEventListener("load",function(){
    scrollFixed();
});

CSS

.area{
    display:flex;
}
.area .mainElm,.area aside{
    flex-basis:50%;
    margin:10px;
}
.fixedElm.myFixed{
    width:calc(50% - 20px) !important;
    position:fixed;
    top:10px;
    left:10px;
    z-index:999;
}

position:fixedと同時にwidthも設定しないと同じ幅を維持できないので注意が必要です。

広告
広告

関連する記事

サムネイル

JSのclassList.toggleでクラスの付け外しを行……

2024年09月04日
classList.toggleとは? まず「classList」とは要素のクラス属性の情報を参照するプロパティで、「classList.add()」や「cla […]
サムネイル

JSで要素が特定のクラスを持つか調べる【classList.……

2024年09月04日
JSで要素が特定のクラスを持つか調べるには? JavaScriptで要素が特定のクラスを持つか調べるには「classList.contains」を使います。 「 […]
サムネイル

JSで文字列の中の任意の位置に別の文字を挿入する【slice……

2024年09月04日
JavaScriptに文字列の中の任意の位置に別の文字を挿入するにはslice()メソッドを利用します。sliceは特定の文字列の任意の位置から任意の文字数分を切り出すメソッドで、これを使って対象の文字列を一旦分解し、挿入したい文字と一緒新しい文字列としてくっつけ直します。
サムネイル

【数値のゼロ埋め】JSのpadStart(padEnd)メソ……

2024年09月04日
JavaScriptのpadStartは対象の文字列が任意の桁数になるまで、その先頭から指定した文字で文字埋めを実行するメソッドです。第一引数に最終的な桁数、第二引数に埋める文字を指定します。
サムネイル

JSのsetIntervalで一定時間ごとに繰り返し処理を実……

2024年08月01日
JSのsetIntervalとは? 業務においてJavaScriptを使って一定時間おきに繰り返し処理を実行させたい場面があり、これまで大まかにしか理解していな […]
サムネイル

JSのsetTimeoutで指定した時間後に処理を実行させる……

2024年08月01日
setTimeout()は、指定した時間が経過したら処理を一度だけ実行するといったタイマーのような設定ができる関数です。一定間隔で処理を繰り返すsetIntervalと異なり、処理が一回しか実行されない点が特徴です。停止させる場合はclearTimeoutを使います。
サムネイル

JSでセレクト値が変更されたらフォームを送信を実行する方法【……

2024年07月02日
ユーザーがセレクトボックスの値を変更したタイミングでフォームの送信を実行するという処理を実装する機会があったので、その方法を備忘録として残しておきます。