今回はjQueryで上にスクロールした時に表示されるヘッダーの作り方を解説します。
デモ
実際の動きはこんな感じです。下にスクロール時は非表示で、上にスクロールすると上からスッと表示されるのがわかるかと思います。
See the Pen
by wagashi000327 (@wagashi000327)
on CodePen.
上にスクロールした時に表示されるヘッダーの作り方
HTML
<body>
<header>ヘッダーです</header>
<main>
<!-- メインコンテンツ -->
</main>
</body>
HTMLは特に注意することはありません。そのまんまですね。
CSS
header {
background-color: #ddd;
height: 100px;
width: 100%;
transition: top 300ms;
}
header.is-fixed {
position: fixed;
z-index: 10;
}
ヘッダーは通常時は固定しないでおきます。
jQueryでスクロール量を取得し、スクロール量がヘッダーの高さを超えたら.is-fixed
を入れて固定するようにします。またスッと出てくるようにtransition
も指定して起きましょう。
top
の値はjQueryで操作することで上から出したり引っ込めたりします。
また、height
の値はjQueryで取得するのでCSSでは指定されていなくても構いません。
jQuery
$(function() {
let pos = 0;
$(window).on('scroll', function () {
const $header = $('header');
const $main = $('main');
const headerHeight = $header.outerHeight();
const currentPos = $(this).scrollTop(); // スクロール量
// スクロール量がヘッダーの高さより大きい場合
if (currentPos > headerHeight) {
// headerを固定
$header.addClass('is-fixed');
$main.css('margin-top', headerHeight);
} else {
// それ以外は固定を解除
$header.removeClass('is-fixed');
$main.css('margin-top', 0);
}
// 上スクロール時
if (currentPos < pos) {
// header引っ込める
$header.css('top', 0);
} else {
//下スクロール時はheader出す
$header.css('top', -headerHeight);
}
pos = currentPos;
});
});
若干コードが長いですが、少しずつ見ていけば大したことはしていません。
最初に処理で必要になる値を変数に入れておきます。
if (currentPos > headerHeight)
ではスクロール量がヘッダーの高さを超えたらヘッダーに.is-fixed
を入れ、メインコンテンツはmargin-top: headerHeight
を入れてヘッダーの高さ分上部に余白を取ります。
こうしないと(ヘッダーを常に.is-fixed
にしていると)メインコンテンツの上の部分とヘッダーがどうしても被ってしまいます。
スクロール量がヘッダーの高さを超えた時点でposition: fixed;
は入りますが、下にスクロールしている時はtop: -headerHeight
が入っているので画面外で固定されている感じになります。ヘッダーの高さより少ないスクロール量ならヘッダーは固定せずに普通に表示しておきます。
if (currentPos < pos)
は上にスクロールしたかどうかを判定しています(上にスクロールしたならtrue)。
上にスクロールしたときはtop: 0
でヘッダーを上からスッと表示します。逆に下にスクロールしたときはtop: -headerHeight
でヘッダーの高さ分画面外に出して、その位置で固定しておきます。
最後のpos = currentPos;
はスクロール量を更新しています。スクロールが発生するとcurrentPos
は最新の値に書き換わりますが、pos
にはpos = currentPos;
にあるように処理の最後の時点で最新だったスクロール量が入ります。
スクロールイベント発生時に最新のスクロール量と前回の処理の最後の時点で最新だったスクロール量を比較して最新のスクロール量のほうが小さい場合(=上にスクロールした場合)にif (currentPos < pos)
はtrueになるわけです。
jQuery側でヘッダーの高さを取得しておくとヘッダーの高さが固定pxじゃない場合でもうまく位置の調整ができます。
またscrollイベント時にヘッダーの高さを取得しているので、ヘッダーの高さがPCとSPで違う場合でもresizeイベントを挟まずに高さを取得できます。
まとめ
上にスクロールした時だけ上からヘッダーを表示させてほしいというのは結構よくあることなので処理の内容を理解しておくとスムーズです。
他にも色々微調整すると更に柔軟な動きができると思うので試してみるとおもしろいです。
参考記事