phi

I'm a Game Programmer and Frontend Engineer passionate about programming education. Math / C / C++ / C# / JavaScript / HTML5 / CSS3 / Python

phiaryjust a creator

jQuery でページ内リンクを全てスムーズスクロールにしよう

9 years ago

jQuery の animate 関数を使ってページトップにスムーズスクロールするボタンを作ろう | phiary』の発展です.

前回は, ピンポイントで要素をスムーズスクロールしましたが, 今回はページ内リンクを持つ全ての要素を判別してすべてスムーズスクロールにする方法を紹介します.

Runstant Demo

今回作成したサンプルです.

Section のリンクを踏むとスムーズスクロールするのがわかるかと思います.

Code

html

目次となるアンカーと, ページトップに移動するアンカーを設置しています.

<body>  
  <h1 id='top'>jQuery でページ内リンクを全てスムーズスクロールにしよう</h1>

  <h2>Table of contents</h2>

  <ul>
    <li><a href='#section1'>Section 1</a></li>
    <li><a href='#section2'>Section 2</a></li>
    <li><a href='#section3'>Section 3</a></li>
    <li><a href='#section4'>Section 4</a></li>
  </ul>

  <h2 id='section1'>Section 1</h2>
  <p class='pad'>Text Text Text Text</p>
  <a href='#top'>▲top</a>

  <h2 id='section2'>Section 2</h2>
  <p class='pad'>Text Text Text Text</p>
  <a href='#top'>▲top</a>

  <h2 id='section3'>Section 3</h2>
  <p class='pad'>Text Text Text Text</p>
  <a href='#top'>▲top</a>

  <h2 id='section4'>Section 4</h2>
  <p class='pad'>Text Text Text Text</p>
  <a href='#top'>▲top</a>

  <br /><br /><br /><br />
  <br /><br /><br /><br />
</body>  

css

スクロール再現用の詰め物

.pad {
  height: 100px;
  margin-bottom: 4rem;
}

javascript

スムーズスクロール実装部分です.

$(function() {
  // スクロールのオフセット値
  var offsetY = -10;
  // スクロールにかかる時間
  var time = 500;

  // ページ内リンクのみを取得
  $('a[href^=#]').click(function() {
    // 移動先となる要素を取得
    var target = $(this.hash);
    if (!target.length) return ;
    // 移動先となる値
    var targetY = target.offset().top+offsetY;
    // スクロールアニメーション
    $('html,body').animate({scrollTop: targetY}, time, 'swing');
    // ハッシュ書き換えとく
    window.history.pushState(null, null, this.hash);
    // デフォルトの処理はキャンセル
    return false;
  });
});

Tips

jQuery でページ内リンクを持つアンカータグのみを取得

jQuery では属性セレクタで, その属性を持つ要素だったり属性の値が条件と
一致する要素のみを取得することができます.

今回は

$('a[href^=#]')

としています.

これは a タグでかつ href 属性が # で始まる要素のみを取得する処理です.

history.pushState を使おう

スムーズスクロールの場合はデフォルトの処理をキャンセルしているので, 普通のページ内リンクと違いハッシュタグが変更されません.

なので自分で設定する必要があるのですが, location.hash = hash としてしまうと 結局画面移動が起きてしまいます.

そこで使えるのが HTML5 から追加された history.poushState です. これは画面に影響を与えることなく url を変更することができるメソッドです.

今回は

window.history.pushState(null, null, this.hash);  

とすることで画面移動することなく url にハッシュタグを付与しています.

スムーズスクロール

こちらを参照下さい. jQuery の animate 関数を使ってページトップにスムーズスクロールするボタンを作ろう | phiary

Reference