jQueryを使って、ページの上へ戻るボタンやページ内リンクをスクロールさせる方法です。基本的には簡単です。
準備
ページ内の特定の場所へ移動するリンクは、移動先のHTML要素にid
属性を設定します。リンク元のhref
属性には#
(フラグメント識別子)に続くid
属性を指定します。
<body id="page-top">
〜
〜
<a href="#page-top">上へ戻る</a>
</body>
以前のHTMLで使われていたname
属性でも機能することがありますが、現代のHTMLではid
属性を使用するのが正しいです。他のURLの特定の場所へのリンクの場合は、URLに続けて#
id
を指定します。
<a href="./location/#accessmap" target="_blank">当社アクセスマップ</a>
jQuery
簡単な例。href
属性が#
から始まるa
要素にクリックのイベントリスナを設けます。例では何もしてないですが、必要なら適宜e.preventDefault()
とかstopPropagation()
とかでイベント伝播の処理も追加します。
$(document).ready(function() {
$('a[href^="#"]').on('click', function(e){
var href = $(this).attr('href');
if (!window.$page) window.$page = $('body, html');
$page.animate(
{ 'scrollTop': ( href == '#' ? $page: $(href) ).offset().top },
{ 'duration': 500, 'easing': 'swing' }
);
return false;
});
});
スクロールさせるためにreturn false;
で本来の動作をキャンセルしているので、クリックしてもアドレスバーが更新されなくなります。履歴が必要な場合は非同期(jQuery AJAX)でページ移動した時の履歴とかのメモで書いたような方法で履歴の操作をする必要が出てくると思います。
$('body, html')
をわざわざwindow.$page
に代入しているのは、クリックイベントが発生するたびに$('body, html')
のパースをさせないためです。別になくてもいいですが無駄な処理は極力なくした方がいいと思います。'body'
でもいいところを'body, html'
としているのは旧バージョンのSafariかなんかの対策です(詳細忘)。
animate()
で指定しているscrollTop
の値は、offset().top
を得るセレクタを条件分岐させています。href="#"
の場合は、ページの一番上に戻れるよう$page
が入ります。
animate()
でscrollLeft
の値を指定すれば左右のスクロールもできます。イージングによっては上下左右を同時にスクロールすると変な動きになるかもしれません。
#ID
の付いたURLで、最初にスクロールさせる
URLの後に#ID
(フラグメント識別子)のついたページをスクロールさせて表示する方法です。
#ID
のついたURLは、アドレスバーを確認でもしない限り、ぱっと見て「ページの途中」であることがわかりにくいこともあります。通常どおりページ最上部を表示した後でスクロールしてから該当箇所へ移動することで、ページの途中へやってきたことがわかりやすくなります。
フラグメント識別子はJavaScript
のlocation.hash
で取得します。流れとしては、location.hash
を保存した後、一度location.hash
のないURLへ書き換えし、ページが表示されてからスクロールします。
var hash = (location.hash && location.hash != '#') ? location.hash: null;
// アドレスバーを書き換える(履歴を追加する)
if (hash) {
window.history.pushState(null, null, location.href.replace(hash, '') );
}
// ロード後処理
$(window).on('load', function() {
// ID属性を持つ要素がある場合のみスクロール実行
if (hash && $(hash).size()) {
// 500ミリ秒後にスクロール
$('body, html').delay(500).animate(
{
'scrollTop': $(hash).offset().top,
'scrollLeft': $(hash).offset().left
},
{ 'duration': 500, 'easing': 'swing' }
);
}
});
URLに#ID
が付いたままだと最初にページ最上部の表示にならないのでhistory.pushState()
のところで、URLを識別子がないものに書き換えています。最初にページトップへ強制的に移動しておくでもいいですしlocation.href
で#
以降がないURLへ移動しておくのでもいいですし、方法はどうでもいいですがとにかく最初にページ最上部を表示しておくようにしています。
で、$(document).ready()
ではなく、ページ読み込みが完了してからスクロールさせるようにしています。このほうが表示済みコンテンツが揃っていてスクロールがスムーズかなと思います。
以上、jQueryを使ってページ上部やページ内リンクをスクロールさせる一例でした。他にも方法あると思いますがどなたかの参考にでもなれば書いた甲斐があるというもので幸いでございます。