一定量スクロールするとヘッダやツールバーがスクロールせずに固定される枠の作成 (jQueryを利用) - jQuery

一定量スクロールするとヘッダやツールバーがスクロールせずに固定される枠を作成するコードを紹介します。

概要

一定量スクロールするとヘッダが固定される画面を実装します。jQueryを利用しない実装方法はこちらの記事を参照してください。

プログラム

事前準備

jQueryを入手します。

コード

下記のコードを記述します。
SimpleFixedBar.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <link rel="stylesheet" href="SimpleFixedBar.css" />
  <meta charset="utf-8" />

  <script src="jquery-2.2.0.js" type="text/javascript"></script>
  <script type="text/javascript">
    $(function () {
      $(window).on('scroll', function () {
        if ($(this).scrollTop() > 96) {       /* header の高さで判定する*/
          $('.fixedbar').addClass('fixed');
        } else {
          $('.fixedbar').removeClass('fixed');
        }
      });
    });

  </script>
</head>
<body>
  <div class="header">ヘッダ</div>

  <div class="fixedbar">固定のバー</div>
  <div class="fixedbarReserved"></div>

  <div>
    <div style="height:60px;background-color:#ff7070">コンテンツ</div>
    <div style="height:60px;background-color:#ffa970">コンテンツ</div>
    <div style="height:60px;background-color:#ffcb70">コンテンツ</div>
    <div style="height:60px;background-color:#ffe670">コンテンツ</div>
    <div style="height:60px;background-color:#fdff70">コンテンツ</div>
    <div style="height:60px;background-color:#d8ff70">コンテンツ</div>
    <div style="height:60px;background-color:#b7ff70">コンテンツ</div>
    <div style="height:60px;background-color:#8bff70">コンテンツ</div>
    <div style="height:60px;background-color:#70ff88">コンテンツ</div>
    <div style="height:60px;background-color:#70ffbd">コンテンツ</div>
    <div style="height:60px;background-color:#70ffe6">コンテンツ</div>
    <div style="height:60px;background-color:#70ceff">コンテンツ</div>
    <div style="height:60px;background-color:#709cff">コンテンツ</div>
    <div style="height:60px;background-color:#7370ff">コンテンツ</div>
    <div style="height:60px;background-color:#9f70ff">コンテンツ</div>
    <div style="height:60px;background-color:#bd70ff">コンテンツ</div>
    <div style="height:60px;background-color:#d870ff">コンテンツ</div>
    <div style="height:60px;background-color:#ff70e9">コンテンツ</div>
    <div style="height:60px;background-color:#ff70d2">コンテンツ</div>
    <div style="height:60px;background-color:#ff70a9">コンテンツ</div>
    <div style="height:60px;background-color:#ff708e">コンテンツ</div>
    <div style="height:60px;background-color:#ff7070">コンテンツ</div>
  </div>
</body>
</html>

SimpleFixedBar.css
.header{
  height:96px;
  background-color:white;
}

.fixedbar{
  position:absolute;
  height:48px;
  width:100%;
  color:white;
  background-color:#303030;
}

.fixedbar.fixed{
  position:fixed;
  top:0px;
}

.fixedbarReserved{
  height:48px; /*fixedbar の高さと合わせる*/
}

解説

fixedbarのDIVタグは、"position:absolute"を指定しています。
JavaScriptの関数は、ウィンドウのonScrollにより実行されます。スクロールされた量が96ピクセル以上であれば、[fixedbar]クラスの要素に"fixed"クラス(サブクラス)を追加します。
fixedbarの"fixed"サブクラスでは、"position:fixed"を指定しており、スクロールによらず、"top:0px" の場所に領域を表示します。これによりスクロールしても表示が固定され続けるバーを表現できます。

実行結果

上記のHTMLファイルを表示します。下図のウィンドウが表示されます。


下方向にスクロールします。通常通りのスクロールです。


白いエリア(ヘッダ)がスクロールにより、スクロールアウトすると、[固定のバー]はそれ以上スクロールアウトせずに画面の上部に残り続けます。赤色の枠が[固定のバー]の裏側にスクロールアウトしています。


[固定のバー]は画面の上部に固定されたまま、[コンテンツ]の枠がスクロールアウトしていきます。


スクロールし続けても、[固定のバー]はウィンドウの上部に固定されたままです。


上方向にスクロールします。赤の[コンテンツ]枠がすべて表示されると、固定のバーがスクロールします。さらに白色の[ヘッダ]もスクロールインしてきます。


画面の最上部までスクロールすると、[ヘッダ]と、[固定のバー]が表示されます。

解説:fixedbarReserved はなぜ必要?

「fixedbarReserved」のDIV枠が一見冗長のように見えますが、「fixedbarReserved」のDIV枠がない場合、下図の表示結果となり、一番上の赤色の「コンテンツ」の一部分が隠れてしまいます。これは、"fixedbar"が "position:absolute" のスタイルのため、赤色の「コンテンツ」は。白色の[ヘッダ]の直下に表示されます。一方[固定のバー]も[ヘッダ]の直後にあるため、[固定のバー]も[ヘッダ]の直後に表示され、同じ位置に重なって表示されます。

補足:fixedbar をRelative にすればよいのでは?

fixbarをrelativeにして
SimpleFixedBar.html
  <div class="header">ヘッダ</div>
  <div class="fixedbar">固定のバー</div>
  <div>コンテンツ</div>
SimpleFixedBar.css
.header{
  height:96px;
  background-color:white;
}

.fixedbar{
  position:relative;
  height:48px;
  width:100%;
  color:white;
  background-color:#303030;
}

.fixedbar.fixed{
  position:fixed;
  top:0px;
}

と記述できそうですが、こちらを実行すると、下図の実行結果になります。

ページ表示時には意図したとおりに表示されます。


下方向にスクロールもできます。


しかし、白の[ヘッダ]がスクロールアウトした瞬間に、赤色のコンテンツが上方向に詰まってしまいます。


これは、白の[ヘッダ]がスクロールアウトした時点で、黒の[固定のバー]のpositionがrelativeからfixedに変わってしまい、赤の[コンテンツ]枠の上部の[固定のバー]がrelativeには含まれずに上方向に詰まってしまうため、このような動作になります。

補足:コードの記述について、

「fixedbarReserved」の枠は下記のどちらの書き方でも正しく動作します。
どちらの記述方式を選択するかは好みかと思われます。
記述方式1
[固定のバー]はスクロールから外れ、画面に固定されるため、独立して記述したい。
  <div class="header">ヘッダ</div>

  <div class="fixedbar">固定のバー</div>
  <div class="fixedbarReserved"></div>

  <div>コンテンツ</div>
記述方式2
意味的には[固定のバー]はfixedbarReservedの領域に配置するバーであるので、fixedbarReservedのDIVタグ内に記述したい。
  <div class="header">ヘッダ</div>

  <div class="fixedbarReserved">
    <div class="fixedbar">固定のバー</div>
  </div>

  <div>コンテンツ</div>

Div枠をidで定義する場合

多くの実装例では、div枠にClassを記述し、選択もクラス名でしています。しかし、多くの場合ページにヘッダは1つのため、div枠をIDで記述したい場合があります。div枠にidを指定した場合のコードを紹介します。
SimpleFixedBarId.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
  <link rel="stylesheet" href="SimpleFixedBarId.css" />
	<meta charset="utf-8" />

  <script src="jquery-2.2.0.js" type="text/javascript"></script>
  <script type="text/javascript">
    $(function () {
      $(window).on('scroll', function () {
        if ($(this).scrollTop() > 96) {         /* header の高さを与える*/
          $('#fixedbar').addClass('fixed');
        } else {
          $('#fixedbar').removeClass('fixed');
        }
      });
    });

  </script>
</head>
<body>
  <div id="header">ヘッダ</div>
  <div id="fixedbar">固定のバー</div>
  <div id="fixedbarReserved"></div>

  <div>
    <div style="height:60px;background-color:#ff7070">コンテンツ</div>
    <div style="height:60px;background-color:#ffa970">コンテンツ</div>
    <div style="height:60px;background-color:#ffcb70">コンテンツ</div>
    <div style="height:60px;background-color:#ffe670">コンテンツ</div>
    <div style="height:60px;background-color:#fdff70">コンテンツ</div>
    <div style="height:60px;background-color:#d8ff70">コンテンツ</div>
    <div style="height:60px;background-color:#b7ff70">コンテンツ</div>
    <div style="height:60px;background-color:#8bff70">コンテンツ</div>
    <div style="height:60px;background-color:#70ff88">コンテンツ</div>
    <div style="height:60px;background-color:#70ffbd">コンテンツ</div>
    <div style="height:60px;background-color:#70ffe6">コンテンツ</div>
    <div style="height:60px;background-color:#70ceff">コンテンツ</div>
    <div style="height:60px;background-color:#709cff">コンテンツ</div>
    <div style="height:60px;background-color:#7370ff">コンテンツ</div>
    <div style="height:60px;background-color:#9f70ff">コンテンツ</div>
    <div style="height:60px;background-color:#bd70ff">コンテンツ</div>
    <div style="height:60px;background-color:#d870ff">コンテンツ</div>
    <div style="height:60px;background-color:#ff70e9">コンテンツ</div>
    <div style="height:60px;background-color:#ff70d2">コンテンツ</div>
    <div style="height:60px;background-color:#ff70a9">コンテンツ</div>
    <div style="height:60px;background-color:#ff708e">コンテンツ</div>
    <div style="height:60px;background-color:#ff7070">コンテンツ</div>

  </div>
</body>
</html>
SimpleFixedBarId.css
body {
  margin: 0px 0px 0px 0px;
}

#header{
  height:96px;
  background-color:white;
}

#fixedbar{
  position:absolute;
  height:48px;
  width:100%;
  color:white;
  background-color:#303030;
}

#fixedbar.fixed{
  position:fixed;
  top:0px;
  /*margin-top:-96px;*/
}

#fixedbarReserved{
  height:48px;
}

解説

ヘッダと固定のヘッダ、fixedbarReservedの枠にidを記述しています。idでの指定のためスタイルシートもIDでのスタイルの定義に変更しています。下方向にスクロールした場合はfixedbarのdiv枠に"fixed"クラスを追加します。この動作は従来と同じです。

表示結果

上記のHTMLファイルをWebブラウザで表示します。下図の画面が表示されます。


下にスクロールします。白の[ヘッダ]がスクロールアウトします。


ヘッダがすべてスクロールアウトすると[固定のバー]は上部に固定されスクロールアウトしません。

著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-06
作成日: 2016-02-18
iPentec all rights reserverd.