スティッキーヘッダーをjQueryでも作っていく
以前紹介した「position:sticky」を使ったものですとIEに対応できません。
サポートが切れたとしても見捨てたくない場合は、jQueryを使ってスティッキーヘッダーを実装しましょう。
こちらのほうが汎用性が高いですし、難易度は高くありませんよ。
この記事の目次
考え方
スティッキーヘッダーの考え方は下方向にスクロールしてナビゲーションがブラウザ最上部まで来たらそのまま最上部の位置に固定する。
上方向にスクロールしたときは元の位置に来たら固定を解除する。
このような考え方をしてあげると良いでしょう。
今回は実装するために4種類のメソッドを使っていきます。
offset()メソッドとtopプロパティ
offsetメソッドは要素の位置を調べるためのメソッド。
topプロパティと合わせて使うと、指定した要素が画面最上部に来るには上から何pxスクロールした位置にあるか調べることができます。
処理でも使いたいので調べたら変数に入れておきましょう。
scrollTop()メソッド
scrollTop()メソッドをwindowに対して使うとスクロール量を調べることができます。
これを利用してスクロール量を調べoffsetメソッドで調べた高さまで到達したら何かをすることができるようになります。
スクロール量を調べるならscrollイベントと組み合わせて、スクロール量を変数に入れてあげると良いでしょう
addClass()メソッド
今回はあらかじめページ最上部に要素を固定するプロパティを記述したクラスセレクタを用意しておきます。
固定したい要素に条件によって、クラスを付けるには「addClass()」メソッドがすごく便利です。
removeClass()メソッド
固定した要素を元に戻すなら今回の例ではクラスを外してあげるのが一番手っ取り早いです。
「removeClass()」メソッドは指定した要素から指定したクラスを外してくれるメソッドなので、これを使ってクラスを外していきます
コードとデモ
HTMLは何の工夫もなく大きな画像の下にnavを配置した形にしています。
元々ページ上部に固定したい要素があっても意味がないのでこのような形にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<body> <header> <img src="top.jpg" alt=""> </header> <nav> <ul> <li><a href="#">LINK</a></li> <li><a href="#">LINK</a></li> <li><a href="#">LINK</a></li> <li><a href="#">LINK</a></li> <li><a href="#">LINK</a></li> </ul> </nav> <main> <div></div> <div></div> <div></div> <div></div> <div></div> </main> <footer></footer> </body> |
CSSは長々と書いても仕方ないのでキモになっている部分だけ抜粋
上のHTMLを見てわかるように存在しないクラス「sticky」に対しての指定を入れておきます
1 2 3 4 5 6 |
.sticky{ position: fixed; top:0; left: 0; width: 100%; } |
jQueryのコードは少ないように思えます。 この後かみ砕いてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$(function(){ var win = $(window); var nav = $('nav'); var navPosi = $('nav').offset().top; win.on('scroll',function(){ var scr = win.scrollTop(); if(scr > navPosi){ nav.addClass('sticky'); }else{ nav.removeClass('sticky'); } }); }); |
jQueryのコードを行ごとにかみ砕いて解説
上で各メソッドは解説していますのでおさらいみたいになります。
1 2 3 |
var win = $(window); var nav = $('nav'); var navPosi = $('nav').offset().top; |
ここでは処理に使う要素を変数に入れて用意しています。
スクロールイベントはスクロールするたびに発生しますので、毎回毎回jQueryオブジェクトを作っていると負荷がかかります。
それを回避するためにあらかじめ作ったjQueryオブジェクトを変数に入れておき、処理で使えば負荷が軽減できるのでやっています。
更に、nav要素が上からどれぐらいの位置にあるか調べて距離を変数に入れています。
1 2 |
win.on('scroll',function(){ var scr = win.scrollTop(); |
ウインドウがスクロールするごとに動くようイベントを設定しています。
スクロールのたびにスクロール量を変数に入れるのがキモ。これで現在のスクロール量が把握できます。
1 2 3 4 5 6 7 |
if(scr > navPosi){ nav.addClass('sticky'); }else{ nav.removeClass('sticky'); } }); }); |
if文内ではスクロール量とnav要素の位置を比べています。
スクロール量がnav要素位置よりも多くなったらtrueになり、animateメソッドが固定用のクラス「sticky」をnav要素につけてくれます。
スクロール量がnav要素の高さよりも少ない場合はクラス「sticky」は外れるのでこれで完成。
ここではnav要素を固定するだけにとどまっていますが、サイドバーを固定したりすることもできますし工夫次第でいろいろなことができそうですね