PROGBLOG Developers Blog

空想家 Developers Blog

稼ぐ力? とにかくスキルが欲しい。

JavaScriptでスムーススクールを実装する

サンプルコード

const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
  for (let i = 0; i < smoothScrollTrigger.length; i++){
    smoothScrollTrigger[i].addEventListener('click', (e) => {
      e.preventDefault();
      const href = smoothScrollTrigger[i].getAttribute('href');
      const targetElement = document.getElementById(href.replace('#', ''));
      const rect = targetElement.getBoundingClientRect().top;
      const offset = window.pageYOffset;
      const gap = 60;
      const target = rect + offset - gap;
      window.scrollTo({
        top: target,
        behavior: 'smooth',
      });
    });
  }

分解考察

正規表現を用いアンカーリンクを取得する

const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');

a要素のhref属性値の文頭が#であるものをすべて取得する。

ページ遷移イベントのキャンセル

e.preventDefault();

aクリック時にpreventDefault();を実行しページ遷移のイベントを中止する。

諸々、定義する

const href = smoothScrollTrigger[i].getAttribute('href');

クリックした要素のhref属性hrefと定義する。

const targetElement = document.getElementById(href.replace('#', ''));

#を空にしたhrefidを持つ要素を取得する。
つまり、飛び先こと。

const rect = targetElement.getBoundingClientRect().top;

飛び先、ブラウザ表示領域からの位置を取得する。

const offset = window.pageYOffset;

現在のスクロール位置を取得する。

const gap = 60;

固定ヘッダーの場合は高さをを指定する。
ここでは60としているが、レスポンシブとかでヘッダー高さが変わる場合は動的に取得すること。
※別記事にて(予定)

const target = rect + offset - gap;

飛び先トップからの位置 + 現在のスクロール位置 - 固定ヘッダーの高さをtargetに代入する。

window.scrollToメソッドでスクロールさせる

window.scrollTo({
    top: target,
    behavior: 'smooth',
});

window.scrollToメソッドを使用しスクロールさせる。
飛び先とスクロールの振るまいはオプションで指定する。
なお、スクロールの振るまいは下記2択とのこと。

滑らかにアニメーションするのか、一回のジャンプで瞬時に行うのか