今回はスティッキーヘッダーをjQueryで作っていきます.スティッキーヘッダーとは,メニュバーやサイト名がついている横長のバーのことです.Webページが長くなればなるほど,ヘッダーのメニュー情報を見るために上まで戻らなければなりません.フッターにも同じ情報を載せてもいいのですが,あまりスマートじゃないですよね.そこで,スクロールしても常時上にあるようなヘッダーを作っていきます.
ヘッダーをCSSのposition:fixedで常に上部に固定してもいいのですが,一番上はヘッダー画像やスライドショーにしたい場合もあると思います.そうなるとCSSだけではうまくいきません.そんなときはウィンドウのスクロール量を管理できるjQueryを使いましょう.
動作原理
スティッキーヘッダーは,初期位置とウィンドのスクロール量を比較します.ヘッダーには{position:absolute}で{bottom:0}が初期値として設定してあります.スクロール量が初期位置を超えると{position:fixed}で{top:0}を指定します.原理としてはこれだけです.そこまで難しくはないですよね.動作イメージは下の図の通りです.スティッキーヘッダーがあるだけで,より使いやく,お洒落なサイトに近づくと思います.
それでは,コードの説明をしていきます.ファイルの構成は以下の通りです.
HTML
<header id="page-header" role="banner">
<div class="inner">
<h1>TamoTechBlog sample page</h1>
</div>
</header>
<header>タグの子要素でclass=innerを持っています.いきなり<h1>タグを入れるより,一つタグを間に入れることで,レイアウトをしやすくします.
SCSS(CSS)
header {
width: 100%;
height: 10vh;
color: #1d1d1d;
background-color: #e6e6fa;
opacity: 0.6;
position: absolute;
bottom: 0;
.inner {
height: 100%;
margin: 0px 20px;
display: flex;
align-items: center;
h1 {
font-size: 20px;
margin-left: 40px;
}
}
}
.sticky {
position: fixed;
top: 0;
}
CSSのポイントは,ヘッダー内の親要素に{position: absolute}を指定することです.このプロパティを指定することで,アニメーションをつけるためにjQueryで位置を操作してもレイアウトが崩れないようになります.
また初期値として,{bottom: 0}を指定してあります.absoluteなのでスクロールしてもその場でずっと固定されるわけではありません.スクロールと一緒に上へ上がっていきます.
「.sticky」はHTMLにはないクラスです.これはスクロールの量によって,ヘッダーに付与するクラスです.これは,ヘッダーをスクロールしても上部に固定される設定です.
jQuery(main.js)
$(function(){
$('header').each(function(){
var $window = $(window),
$header = $(this),
//ヘッダーボックスの初期位置を取得
headeBoxTop = $header.offset().top;
//スクロールイベントを監視
$window.on('scroll',function(){
//スクロール量がヘッダーボックスの
//初期位置より多ければクラスを追加
if($window.scrollTop()>headeBoxTop){
$header.addClass('sticky');
} else {
$header.removeClass('sticky');
}
});
//ウィンドウのスクロールイベントを発生させる
$window.trigger('scroll');
});
});
まず初めにヘッダーの初期位置を取得します.ブラウザのウィンドウに対してスクロールイベントを設定します.スクロールした時にスクロール量がヘッダーの初期位置を超えた時に,ヘッダーに「sticky」クラスを付与します.
最後の1行は,中途半端な位置でページをリロードした時に,スクロールしてないとみなされる場合があります.その場合ヘッダーの位置が想定した場所にないことがあります.これを避けるためにスクロールイベントを発生させておきましょう.
サンプルページはこちらからも閲覧できます.
サンプルページのコードはこちらからダウンロードできます.