同じページ内のスムーズスクロールは簡単ですが、別ページからリンクをクリックしてそのリンクの箇所にスムーズスクロールするのは結構面倒です。
しかし、意外とよくある要望なので抑えておくといいでしょう。
やりたいことのイメージ
あまり言葉だとイメージしずらいかと思うので、以下をご覧ください。
下層ページなどの別ページにてリンクをクリックした際に、遷移先の該当箇所にスムーズスクロールしたいというのがこの記事の内容です。
実装コード
今回は先ほど載せたイメージ図をもとにしたコードを紹介します。
つまり、下層ページにてsection Aリンクをクリックし、TOPページのsection Aにスムーズスクロールする場合です。
まずは遷移先のTOPページのHTMLです。
<!-- 諸々省略 -->
<section data-id="#sectionA">
<!-- 諸々省略 -->
</section>
<!-- 諸々省略 -->
data-id属性に#sectionAを付与します
続いて、下層ページのHTMLです。
<!-- 諸々省略 -->
<a href="[TOPページのURL]/#sectionA">section A</a>
<!-- 諸々省略 -->
href属性は[TOPページのURL]/#sectionA
を付与します。
最後にJavaScript(jQuery)です。
$(function () {
var hash = location.hash;
if(hash) {
var target = $('[data-id="'+hash+'"]');//offset()を使うためjQueryオブジェクト化
if(!target.length) return;/* targetがなかったときはそれ以降の処理をしない */
// 移動先を数値で取得
$(window).on('load',function(){
history.replaceState('','','./');/* 再読み込みしたときにスムーススクロールしないようにhashを取り除く */
//loadの中に書くことで、画像を読み込んだ後に実行されるようになる
//loadの中に書かないと画像が読み込まれる前にoffset().topしてしまうため、正しい位置にならない
var position = target.offset().top;
//headerの高さ
var headerHeight = $('#header').innerHeight();
position = position - headerHeight;
// スムーススクロール
$('body,html').animate({scrollTop:position}, 300, 'swing');
});
}
});
これで完成です。
17行目のところでヘッダーの高さ分を引いていますが、僕が制作する大抵のサイトがヘッダーをfixedにしているためこのようにしています。