動作
サイト上部に固定したヘッダーやナビなどが、下にスクロールすると消え、上にスクロールすると現れる実装方法の紹介です。
jQuery を使わず素の JavaScript で、かつ window.requestAnimationFrame()
メソッドを使います。サイトが遅く重くならず、スピードが犠牲になりません。また、スムーズなアニメーションを表現できます。
実装後の動作は、このようなものです。サイト上部に、高さ 56px・背景色が赤のヘッダーを作っています。そのヘッダーが、下スクロール時に消え、上スクロール時に現れます。
HTML
今回は、ヘッダーを例とします。
HTML は、非常に単純なものです。
<header id="header">サイト名やナビなどを書く</header>
requestAnimationFrame() を使った JavaScript
次は JavaScript です。requestAnimationFrame()
を使い、スクロールイベントを設定します。
let offset = 0;
let lastPosition = 0;
let ticking = false;
const header = document.getElementById('header');
const height = 56;
const onScroll = () => {
if (lastPosition > height) {
if (lastPosition > offset) {
header.classList.add('head-animation');
} else {
header.classList.remove('head-animation');
}
offset = lastPosition;
}
};
document.addEventListener('scroll', () => {
lastPosition = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(() => {
onScroll();
ticking = false;
});
ticking = true;
}
});
参考
コードを説明します。
const target = document.getElementById('header');
4 行目で、対象の要素の id を指定します。今回は <header> の id を指定しています。
const height = 56;
5 行目は、対象の要素が隠れ始める位置の指定です。56
であれば、サイトの上部から 56px スクロールした地点から要素が隠れます。
0
の指定も可能ですが、アニメーションが性急に感じるかもしれません。対象の要素の高さと同じ値の指定がおすすめです。
また、下にスクロールしても、ある程度の位置まで要素を隠したくない場合があります。その場合には、400
など少し多めの任意の値を指定します。
target.classList.add('head-animation');
7 行目から 16 行目は、スクロール時の処理の設定です。そのうち 10 行目で、下にスクロールしている時に、対象の要素の class に head-animation
を追加しています。
target.classList.remove('head-animation');
12 行目で、上にスクロールしている時は、対象の要素の class から head-animation
を削除しています。
offset = lastPosition;
14 行目は、スクロール量の更新です。
18 行目から 27 行目は、requestAnimationFrame()
の設定です。MDN のやり方をそのまま真似ています。元ネタの Leaner, Meaner, Faster Animations with requestAnimationFrame で、スクロールイベントをそのまま使うべきではない理由をご覧いただけます。
transform を使った CSS
あとは CSS を指定すれば完成します。CSS の一例は、下記のとおりです。
#header {
background: #fff;
box-shadow: 0 4px 8px -3px rgba(17, 17, 17, .06);
height: 56px;
position: fixed;
top: 0;
transition: .3s cubic-bezier(.4, 0, .2, 1);
width: 100%;
z-index: 199999;
}
.head-animation {
transform: translateY(-100%);
}
対象の要素に position: fixed;
と top: 0;
を指定し、サイト上部に固定します。
そして、JavaScript で追加する class の head-animation
に、transform: translateY(-100%);
を指定します。これで下にスクロール時は、対象の要素が上に消えていきます。
要素の高さを使った top: -56px;
でも同じ表現はできますが、GPU アクセラレーションが可能な transform
での指定がおすすめです。ブラウザの負荷を抑えられる上に、よりアニメーションが滑らかになります。