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

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

投稿日:

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

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

本記事は執筆時点(2024年04月12日)の情報をベースにしております。掲載している情報が最新ではない可能性がありますので何卒ご容赦ください。

広告
広告

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でビデオやピクチャが現在どのソース要素を表示しているか取……

2024年11月07日
表示中のsource要素のファイルパスをJSで取得したい picture要素(video)要素とsource要素を使って画像(動画)を表示させている時に、Jav […]
サムネイル

JSで入力値が英数字や半角かどうか即時文字チェックする【ma……

2024年10月02日
JavaScriptのmatch()は、正規表現を使って対象の文字列の中に一致するものがあるか検索できるメソッドです。このページではテキストボックスに入力された文字が数字や半角かどうかチェックする機能をmatchメソッドを使って実装する方法ついてご紹介します。
サムネイル

JSでHTMLのデータ属性を取得・更新する方法【datase……

2024年10月02日
JavaScriptのdatasetで要素のdata属性を操作する JavaScriptのdatasetは、HTML要素に設定されたデータ属性(data-*** […]
サムネイル

JavaScriptでラジオボタンの値(value)を取得す……

2024年10月02日
JSでラジオボタンの値を取得・操作する JavaScriptによるラジオボタンの操作(値の取得やチェックの切り替え)の方法を備忘録として残しておきます。 JSで […]
サムネイル

JSで大文字から小文字(小文字から大文字)へ変換する方法

2024年10月02日
JavaScriptで大文字と小文字を変換する JavaScriptを使った文字検索フォームを作るにあたり、大文字小文字どちらで入力されても良いよう、変換処理を […]
サムネイル

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

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

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

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