javascriptでページトップスクロールとページ内スクロールのコンフリクト回避

Filed under: JavaScript — kdcs @ 24年2月13日 火曜日

cssでスムーズスクロールが可能になっているが、ios(Safari15.4)以降でないと効かない。

html {
    scroll-behavior: smooth;
    scroll-padding-top: 60px;
}

そのため、javascriptでの対応となるがページトップスクロールとページ内スクロールは内容が被ることが多いので記述がコンフリクトしないようにしなければ、どちらも動作しなくなってしまう。

コンフリクト回避できる記述があったのでこちらに保存
この記述ではオフセット(停止位置を任意の値だけずらす)ことも可能

このjavascriptを使用してもiosやIEではスムーズスクロールが出来ないのでpolyfillのsmoothscroll.jsを利用する。
※スクロールのjavascriptより前にsmoothscroll.jsを読み込ませる。

smooth scroll behavior polyfillというpolyfillパッケージが公開されており、smoothscroll.jsを読み込むことで以下のモダンブラウザでもスムーズスクロールが実現可能。
srcをクリックするとsmoothscroll.jsが表示される。

こちらはiosやIE以外に適用できるスクロールの記述

document.addEventListener('DOMContentLoaded', () => {
  // ヘッダーエレメントを取得。
  const headerElement = document.querySelector('.header');
  // バッファ(オフセット)の値を設定。スムーズスクロールの際にこの値だけ位置をずらす。
  const buffer = 60;
  // href属性の値が"#"から始まるすべての<a>要素を取得
  document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    // 各<a>要素にクリックイベントのリスナーを追加
    anchor.addEventListener('click', (event) => {
      // デフォルトのクリック動作をキャンセル
      event.preventDefault();
      // ヘッダーの高さを取得。ヘッダーエレメントがない場合は0とする。
      const headerHeight = headerElement ? headerElement.offsetHeight : 0;
      // スクロール時の総オフセットを計算(ヘッダーの高さ + バッファ)
      const totalOffset = headerHeight + buffer;
      // クリックされた<a>要素のhref属性の値を取得
      const targetId = anchor.getAttribute('href');
      // ターゲットとなるエレメントを取得
      const targetElement = document.querySelector(targetId);
      // IDが指定されていない、またはターゲットのエレメントが存在しない場合
      if (targetId === "#" || targetId === "" || !targetElement) {
        alert('適切なスクロール先がありません');
        return; // 以降の処理をスキップ
      }
      // smoothScroll関数を呼び出してスムーズスクロールを実行
      smoothScroll(targetElement, totalOffset);
    });
  });
  // スムーズスクロールを行う関数
  const smoothScroll = (target, offset) => {
    // スクロール先の位置を計算
    const targetPosition = target.getBoundingClientRect().top + window.scrollY - offset;
    // 計算された位置にスムーズにスクロール
    window.scroll({
      top: targetPosition,
      behavior: 'smooth'
    });
  }
});

サイト内検索

カテゴリー

最近の投稿

« |javascriptでページトップスクロールとページ内スクロールのコンフリクト回避| »
↑上に戻る