一定量スクロールするとヘッダやツールバーがスクロールせずに固定される枠を作成するコードを紹介します。
概要
一定量スクロールするとヘッダが固定される画面を実装します。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