同じページ内のスムーズスクロールは簡単ですが、別ページからリンクをクリックしてそのリンクの箇所にスムーズスクロールするのは結構面倒です。

しかし、意外とよくある要望なので抑えておくといいでしょう。

やりたいことのイメージ

あまり言葉だとイメージしずらいかと思うので、以下をご覧ください。

下層ページなどの別ページにてリンクをクリックした際に、遷移先の該当箇所にスムーズスクロールしたいというのがこの記事の内容です。

実装コード

今回は先ほど載せたイメージ図をもとにしたコードを紹介します

つまり、下層ページにて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にしているためこのようにしています。