jQueryを使用して、シングルページでナビゲーションに現在地を表示するサンプルを作成しました。
デモページはこちらになります。
■HTML
ナビゲーション部分とコンテンツ部分のHTMLの抜粋です。
ページ内リンクで各コンテンツに遷移します。
<ul id="gnav">
<li><a href="#contents01">コンテンツA</a></li>
<li><a href="#contents02">コンテンツB</a></li>
<li><a href="#contents03">コンテンツC</a></li>
<li><a href="#contents04">コンテンツD</a></li>
</ul>
~略~
<div id="contents">
<div class="inner">
<div id="contents01">
<h2>コンテンツA</h2>
コンテンツAの領域
</div>
<div id="contents02">
<h2>コンテンツB</h2>
コンテンツBの領域
</div>
<div id="contents03">
<h2>コンテンツC</h2>
コンテンツCの領域
</div>
<div id="contents04">
<h2>コンテンツD</h2>
コンテンツDの領域
</div>
</div>
</div>
■JavaScript
JavaScriptのコードは下記になります。
$(function() {
// ナビゲーションのリンクを指定
var navLink = $('#gnav li a');
// 各コンテンツのページ上部からの開始位置と終了位置を配列に格納しておく
var contentsArr = new Array();
for (var i = 0; i < navLink.length; i++) {
// コンテンツのIDを取得
var targetContents = navLink.eq(i).attr('href');
// ページ内リンクでないナビゲーションが含まれている場合は除外する
if(targetContents.charAt(0) == '#') {
// ページ上部からコンテンツの開始位置までの距離を取得
var targetContentsTop = $(targetContents).offset().top;
// ページ上部からコンテンツの終了位置までの距離を取得
var targetContentsBottom = targetContentsTop + $(targetContents).outerHeight(true) - 1;
// 配列に格納
contentsArr[i] = [targetContentsTop, targetContentsBottom]
}
};
// 現在地をチェックする
function currentCheck() {
// 現在のスクロール位置を取得
var windowScrolltop = $(window).scrollTop();
for (var i = 0; i < contentsArr.length; i++) {
// 現在のスクロール位置が、配列に格納した開始位置と終了位置の間にあるものを調べる
if(contentsArr[i][0] <= windowScrolltop && contentsArr[i][1] >= windowScrolltop) {
// 開始位置と終了位置の間にある場合、ナビゲーションにclass="current"をつける
navLink.removeClass('current');
navLink.eq(i).addClass('current');
i == contentsArr.length;
}
};
}
// ページ読み込み時とスクロール時に、現在地をチェックする
$(window).on('load scroll', function() {
currentCheck();
});
// ナビゲーションをクリックした時のスムーズスクロール
navLink.click(function() {
$('html,body').animate({
scrollTop: $($(this).attr('href')).offset().top
}, 300);
return false;
})
});
大まかな処理は下記になります。
-
ナビゲーションのリンクから、各コンテンツの開始位置と終了位置を取得しておく。
-
スクロールする毎に、現在のスクロール位置を取得。
そのスクロール位置が、1で取得した開始位置と終了位置の間にあるコンテンツを探す。 - 2で一致したナビゲーションにclass="current"をつける。