【更新日 :

【脱Jquery】javascriptでスムーススクロールを実装する

Category: JavaScript

Vanilla JSでスムーススクロールを実装したサンプルです。
イージングのカスタマイズにも対応しています。


See the Pen
Smooth Scroll JavaScript (Easing support)
by web_nak (@web_walking_nak)
on CodePen.


HTML

<p><a href="#img">画像まで移動</a></p>
<p id="img"><img src="https://picsum.photos/id/1003/500/600" alt="" width="500" height="600"></p>

アンカーリンクを設定してください。特に特別な実装はありません。

JS

/**
 * スムーススクロール関数
 */
const smoothScroll = () => {
  //スクロールリンク取得
  const targets = document.querySelectorAll('a[href^="#"]');
  if(targets.length === 0) {
    return;
  }

  /*
    イージング設定
      ・参考サイト
        https://github.com/danro/jquery-easing/blob/master/jquery.easing.js
        https://noze.space/archives/432#index-3
    「t:アニメーションの経過時間」「b:始点」「c:変化量」「d:変化にかける時間」
  */
  const easing = (t, b, c, d) => {
    return c * (0.5 - Math.cos((t / d) * Math.PI) / 2) + b;
  }

  //スクロール速度
  const animeSpeed = 600;
  const scrollBusyClass = 'is-scroll-busy';
  const body = document.body;
  const bodyClassList = body.classList;

  //クリックイベント設定
  targets.forEach(target => {
    target.addEventListener('click', event => {
      event.preventDefault();

      //スクロールイベント重複防止
      if (bodyClassList.contains(scrollBusyClass)) {
        return;
      }
      bodyClassList.add(scrollBusyClass);

      //hrefから遷移先を取得
      const href = target.getAttribute('href');
      const scrollStopTarget = document.querySelector(href == '#' || href == '' ? 'html' : href);

      //遷移先が存在しない場合は処理しない
      if (!scrollStopTarget) {
        return;
      }

      //移動先取得
      const scrollStopTop = scrollStopTarget.getBoundingClientRect().top;

      //現在のスクロール量
      const scrollTop = window.pageYOffset;

      //アニメーション開始時間
      let start;
      //スクロールアニメーション関数
      const startAnime = () => {
        requestAnimationFrame(mainAnime);
      }
      const mainAnime = timestamp => {

        //イベント発生後の経過時間
        // start未定義時のみtimestampを代入することで一度だけstartに数値を格納する
        if (start === undefined) {
          start = timestamp;
        }

        // 経過時間を監視
        const elapsedTime = timestamp - start;

        //アニメーション終了処理
        if (elapsedTime > animeSpeed) {
          //実行中class削除
          bodyClassList.remove(scrollBusyClass);

          //処理を終了
          return;
        }

        //スクロール処理
        window.scrollTo(
          0,
          //「アニメーションの経過時間」,「始点」,「変化量」,「変化にかける時間」
          easing(elapsedTime, scrollTop, scrollStopTop, animeSpeed)
        );
        startAnime();
      }

      //アニメーション初回呼び出し
      startAnime();
    });
  });
}

イージング設定やスクロール速度はサイトに合わせて編集してください。

関数の呼び出し

任意の場所で以下を実行し関数を呼び出してください。

//スムーススクロール関数呼び出し
smoothScroll();

参考リンク

Category : JavaScript