【更新日 : 】
【脱Jquery】JavaScriptで上スクロール時に表示される追従ヘッダーを実装する
- Category:
- JavaScript
- Tags:
- css, css3, JavaScript, transition, Vanilla JS, アニメーション, レイアウト, 脱Jquery, 自作関数
JavaScriptで追従ヘッダーを実装したサンプルです。
上スクロールもしくは、ページ最下部に到達すると表示されます。
表示はディレイ時間(0.5秒)を設けているので、一瞬上にスクロールしたら即表示されるような挙動も防止しています。
See the Pen Fix Header Vanilla JS (scroll up to show) by web_nak (@web_walking_nak) on CodePen.
HTML
<header id="global-header" class="global-header">
<p>追従ヘッダー(上方向にスクロールすると表示)</p>
</header>
CSS
transitionはお好みで設定してください。
.global-header {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
--transition: transform .6s cubic-bezier(.19,1,.22,1);
}
.global-header.is-fix {
position: fixed;
transform: translate3d(0,-100%,0);
}
.global-header.is-hide {
transform: translate3d(0,-100%,0);
transition: var(--transition);
}
.global-header.is-show {
transition: var(--transition);
transform: translate3d(0,0,0);
}
JavaScript
表示するまでのディレイ時間(showDelay)の変更や対象class名や変更したい場合は、初期設定のoptionsを編集してください。
//ヘッダー追従関数(上スクロール時、ページ最下部到達時のみ表示)
function headerScrollFunc() {
'use strict';
//追従ヘッダー取得
const header = document.getElementById('global-header');
//初期設定
const options = {
fixClass: 'is-fix', //追従class
hideClass: 'is-hide', //追従中 非表示class
showClass: 'is-show', //追従中 表示class
showDelay: 500 //表示するまでのディレイ時間(指定秒数(ミリ秒)以上、下スクロールしなければ表示)
};
//ヘッダーが存在するかチェック
if(!header) {
return false;
}
//スクロール開始位置
options.startPosi = 0;
//上スクロール判別フラグ
options.upFlg = false;
//表示タイマー用設定
options.setTimeoutFlg = false;
options.setTimeoutId = 0;
//ヘッダーfix関数呼び出し
window.addEventListener('resize', function() {
headerFix(options);
});
window.addEventListener('scroll', function() {
headerFix(options);
});
//追従設定
function headerFix(options) {
//追従前のヘッダー位置(ヘッダーの位置によって色々パターンがあると思います)
const headerBasePosi = 0;
/*
ヘッダーを追従させる位置
画面の高さ、特定の要素の位置から追従開始など、色々パターンがあると思います。
今回はヘッダーの高さを超えたら追従処理を開始
*/
const headerFixPosi = header.clientHeight;
//スクロール量(ウィンドウの上端)取得
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
//class設定
const fixClass = options.fixClass;
const showClass =options.showClass;
const hideClass =options.hideClass;
//上下スクロール判別
//下スクロール(新規取得したスクロール量がoptions.startPosiを超えている)
if (scrollTop > options.startPosi) {
//上スクロール判別フラグを無効化
options.upFlg = false;
//表示タイマーリセット
clearTimeout(options.setTimeoutId);
options.setTimeoutFlg = false;
//スクロール量がヘッダーを追従させる位置を超えているか
if(scrollTop > headerFixPosi) {
//追従class追加
header.classList.add(fixClass);
}
//ページの高さ取得
const pageHeight = document.documentElement.scrollHeight;
//下スクロール位置取得
const scrollBottom = window.innerHeight + scrollTop;
//ページの最下部だった場合はヘッダーを表示
if (pageHeight <= scrollBottom) {
headerShow(hideClass,showClass);
//ページの途中だった場合
} else {
//表示されている場合ヘッダーを非表示
if(header.classList.contains(showClass)) {
headerHide(hideClass,showClass);
}
}
//上スクロール(新規取得したスクロール量がoptions.startPosi以下)
} else {
//上スクロール判別フラグを有効化
options.upFlg = true;
//ヘッダーが追従前の位置に来ている場合は追従を終了する
if(scrollTop <= headerBasePosi) {
//全ての追従用classを削除
header.classList.remove(fixClass,showClass,hideClass);
//ヘッダーが追従前の位置を超えている場合
} else {
//表示タイマーが設定されていなければタイマーを設定
if(!options.setTimeoutFlg) {
//表示タイマーセット
options.setTimeoutFlg = true;
//指定秒数以上、下スクロールしていない場合のみヘッダーを表示
options.setTimeoutId = setTimeout(function() {
if(options.upFlg && header.classList.contains(fixClass)) {
headerShow(hideClass,showClass);
}
}, options.showDelay);
}
}
}
//スクロール開始位置を更新
options.startPosi = scrollTop;
}
//追従ヘッダー表示関数
function headerShow(hideClass,showClass) {
header.classList.remove(hideClass);
header.classList.add(showClass);
}
//追従ヘッダー非表示関数
function headerHide(hideClass,showClass) {
header.classList.remove(showClass);
header.classList.add(hideClass);
}
}
関数の呼び出し
任意の場所で以下を実行し関数を呼び出してください。
//ヘッダー追従関数呼び出し
headerScrollFunc();