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

JavaScript でするするスクロール(スムーススクロール)を実装したのでご紹介します。

ページ内の特定の位置、またはページトップまでスムーズにスクロールするためのシンプルな JavaScript 関数をご紹介します(IEを除くモダンブラウザで動作します)。

ページ上部に固定ヘッダーがある場合でも、スクロールしたときにヘッダーに隠れてしまわないように、ヘッダー高さを考慮してスクロールするオプションも付けました(必要だったので)。

処理に関する簡単な説明はコメントとして追記してあります。

/**
 * 指定された要素、IDの要素またはページのトップまでスムーズにスクロールする関数。
 * @param {HTMLElement|string|null} [target=null] - スクロール先の要素、またはそのID。指定されない場合はページのトップまでスクロールします。
 * @param {Object} [options={}] - オプションのオブジェクト。
 * @param {string} [options.headerId] - ヘッダー要素のID。ヘッダーの高さをスクロール位置の計算に考慮する場合に指定します。
 */
export function smoothScrollTo(target = null, options = {}) {
    let targetElement;

    // スクロール先の要素またはページのトップを取得
    if (typeof target === 'string') {
        targetElement = document.getElementById(target);
    } else if (target instanceof HTMLElement) {
        targetElement = target;
    } else {
        targetElement = null;
    }

    // pageYOffset は scrollY でもいいけど、pageYOffset の方がブラウザサポートが若干良さそう
    const targetPosition = targetElement ? targetElement.getBoundingClientRect().top + window.pageYOffset : 0;

    // ヘッダー要素の高さを考慮する場合、その高さを取得
    let headerHeight = 0;
    if (options.headerId) {
        const headerElement = document.getElementById(options.headerId);
        if (headerElement) {
            headerHeight = headerElement.offsetHeight;
        }
    }

    // スクロール位置の計算。ヘッダーの高さを引いて調整
    const scrollToPosition = targetPosition - headerHeight;

    // スムーズスクロールの実行
    window.scrollTo({
        top: scrollToPosition,
        behavior: 'smooth'
    });
}

使い方

特定の要素までスクロール

次のように、スクロール先の要素のIDを指定して関数を呼び出します。

smoothScrollTo('ターゲット要素のID');

// IDではなくHTMLElementを渡してもOK
const target = document.getElementById('ターゲット要素のID');
smoothScrollTo(target);

ページトップまでスクロール

引数に何も指定せずに関数を呼び出すと、ページのトップまでスクロールします。

smoothScrollTo();

ヘッダーの高さを考慮する場合

ヘッダー要素のIDを options オブジェクトで指定することで、ヘッダーの高さを考慮したスクロールになります。

smoothScrollTo('someElementId', { headerId: 'ヘッダー要素のID' });

ページ内リンクのaタグに適用

href 属性の値が#から始まるaタグをクリックしたときにするするスクロールするようにします。

document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    anchor.addEventListener('click', function (e) {
        e.preventDefault();

        const href = anchor.getAttribute('href');
        // hrefが"#"だけの場合はページトップへ、それ以外は指定IDまでスクロール
        const targetId = href === '#' ? null : href.replace('#', '');

        // headerIdはオプションです。必要に応じて変更してください。
        smoothScrollTo(targetId, { headerId: 'ヘッダー要素のID' });
    });
});
Published 2023-10-03
Updated 2023-10-03

「JavaScript」カテゴリの記事一覧