よくあるエレベーターメニューをプラグインなし、jQueryで自作してみる
よくあるエレベーターメニュー。このサイトにもついていますね。 自分で作ればカスタマイズも自由自在! ってことで忘れがちな作業内容をメモしてみます。
01ページ内スムーススクロールを実装する
エレベーターメニューを実装するにあたり、まずはページ内リンクを作成します。エレベーターメニューのHTMLはこちら。
HTML
<nav id="elevator">
<ul>
<li><a href="#section01">01</a></li>
<li><a href="#section02">02</a></li>
<li><a href="#section03">03</a></li>
<li><a href="#section04">04</a></li>
<li><a href="#section05">05</a></li>
</ul>
</nav>
続いて、javascriptはこちら。
javascript
$('a[href^="#"]').click(function(){
var href = $(this).attr('href');
var target = $(href == '#' || href == '' ? 'html' : href );
var position = target.offset().top;
$('html, body').animate({scrollTop:position}, 400, 'swing');
return false;
});
セレクタの$('a[href^="#"]')
はリンク先が#から始まる文字列、つまりページ内リンクを指しています。
3行目でリンク先を取得し、4行目のtarget.offset().top;
で、トップからリンク先までの距離を取得しています。
デモ画面を用意してみたのでこちらをご覧ください。
デモはこちら
右側のリンクをクリックすると、スクロールでセクションを移動できますね!!
02現在地を取得する
エレベーターメニューを実装するにあたり、自分が今どのセクションにいるのかを表示したいですよね!!そのために、まずはページトップを起点とした自分の現在位置を取得する必要があります。
$(window).on('scroll', function(){
var top = $(window).scrollTop();
$('#myPosition').html(top);
});
スクロール時に現在位置を取得して、#myPositionに現在位置を表示させるコードを書いてみました!
ただ、このままだとページを表示した際に現在位置が取得できないので、下記のように書き換えてみます。
$(window).on('load resize scroll', function(){
var top = $(window).scrollTop();
$('#myPosition').html(top);
});
こうすることで、ページロード時、リサイズ時、スクロール時に現在位置を取得するようにできました!
デモはこちら
03各セクションの開始と終わり位置を取得する
さて、自分の現在位置は簡単に取得できました。今度は、自分の位置がどのセクションのどの位置にいるかを比較したいですね。
そのために、まずは各セクションの開始と終わり位置を取得しましょう。
エレベーターメニューに対応するセクションを洗い出し
そもそも、エレベーターメニューで表示したいセクションがいくつあるのか、まずは洗い出しをしましょう。
var elIndex = $('#elevator a');
for(i=0; i < elIndex.length; i++){
var elLink = elIndex.eq(i).attr('href');
}
for文を使って、#elevatorのリンクの数だけ処理を繰り返します。
こうすることで、エレベーターメニューに対応するセクションが洗い出しできますね。
各セクションの開始位置と終わり位置を取得
さて、エレベーターメニューに対応するセクションの洗い出しをしたら、それぞれの開始位置と終わり位置を調べましょう。先ほどのコードに一部つけ足して、
var elIndex = $('#elevator a');
for(i=0; i < elIndex.length; i++){
var elLink = elIndex.eq(i).attr('href'),
secTop = $(elLink).offset().top,
secBottom = secTop + $(elLink).outerHeight(true);
}
5行目の$(elLink).outerHeight(true)
でセクションの高さを取得しています。
デモ画面では、分かりやすくそれぞれのセクションの開始位置と終わり位置を表示しているので、自分の現在地と比較しながらスクロールしてみてください。
デモはこちら
04現在位置をエレベーターに反映する
さて、これまででエレベーターメニューに必要なパーツは出そろったので、あとはスクロール時に現在位置をエレベーターメニューに反映する動きを実装したいと思います。
var sectionArr = new Array(),
elIndex = $('#elevator a');
for(i=0; i < elIndex.length; i++){
var elLink = elIndex.eq(i).attr('href');
sectionArr[i] = elLink;
}
$(window).on('load resize scroll', function(){
var top = $(window).scrollTop();
for(i=0; i < sectionArr.length; i++){
var target = sectionArr[i],
secTop = $(target).offset().top,
secBottom = secTop + $(target).outerHeight(true);
if(secTop <= top && secBottom >= top){
elIndex.removeClass('current');
elIndex.eq(i).addClass('current');
}
}
});
スクロールによって、エレベーターメニューの現在位置が自動で切り替わるようになりました!
ただ、このままだと、セクションの表示位置が画面の頭まで来ないと、エレベーターがアクティブ表示になりません。これは、セクションの範囲と自分の現在位置を比較する際に、自分の現在位置を画面の頭に設定しているからなんですね!なので、下記のように自分の現在位置を工夫してみることにします。
var sectionArr = new Array(),
elIndex = $('#elevator a');
for(i=0; i < elIndex.length; i++){
var elLink = elIndex.eq(i).attr('href');
sectionArr[i] = elLink;
}
$(window).on('load resize scroll', function(){
var top = $(window).scrollTop() + ($(window).height() / 2);
for(i=0; i < sectionArr.length; i++){
var target = sectionArr[i],
secTop = $(target).offset().top,
secBottom = secTop + $(target).outerHeight(true);
if(secTop <= top && secBottom >= top){
elIndex.removeClass('current');
elIndex.eq(i).addClass('current');
}
}
});
これで、セクションが画面の中央に来た時にエレベーターを切り替えるように出来ました。ポイントは、自分の現在位置の基準を画面中央にしている点ですね!$(window).height() / 2
の部分を変えると、どの位置で切り替えるか調整できます。参考になれば…。
この記事が役に立ったらシェアしてください!