[js]ページ内スクロール改訂版

何回いじったんだろうね

改訂版

いつものようにjQuery版。

$(function () {
    //リンク先が「#」だった場合は除外する
    $('a[href^="#"]:not([href="#"])').on('click', function (e) {
        e.preventDefault();

        const href = decodeURIComponent($(this).attr('href'));
        const target = $(href.length > 1 ? href : 'html');

        //遷移先が存在しなかったらスクロールさせない
        if (!target.length) return;

        //headerの高さ取得
        const headerHeight = 0;  //常時取得しない
        //const headerHeight = $('header').innerHeight();  //常時取得
        //const headerHeight = $('header.sp').innerHeight() || 0;  //headerに.spを付与してたら取得

        const position = target.offset().top - headerHeight;
        const speed = 500;

        $('html, body').animate({ scrollTop: position }, speed, 'swing');
    });
});

headerHeightはheaderの高さを取得するために用意する変数。
いろんな状況によって指定の仕方が変わる。
要らない場合は0にすればいい(そもそもheaderHeightに関する記述を削除しちゃえば良い)。

headerを固定表示してる場合はheaderの高さ分をズラさないと、スクロール先の要素がheaderと被ってしまう。
レスポンシブデザインでsp表示時のみheaderを固定表示にする場合もある。

バニラjsだとこう。

document.addEventListener('DOMContentLoaded', function () {
    const links = document.querySelectorAll('a[href^="#"]:not([href="#"])');

    links.forEach(function (link) {
        link.addEventListener('click', function (e) {
            e.preventDefault();

            const href = decodeURIComponent(this.getAttribute('href'));
            const target = document.querySelector(href.length > 1 ? href : 'html');

            if (!target) return;

            //取得しない
            const headerHeight = 0;
            //常時取得
            //const header = document.querySelector('header');
            //const headerHeight = header.offsetHeight;
            //headerに.spを付与してたら取得
            //const header = document.querySelector('header.sp');
            //const headerHeight = header ? header.offsetHeight : 0;

            const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - headerHeight;

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

長い。

外部リンクからもスクロールさせたい

urlに#~がついてた場合にスクロールさせたい場合はこれを追加。

$(function () {
    const hash = window.location.hash;
    if (hash && $(hash).length) {
        const headerHeight = 0;  //常時取得しない
        //const headerHeight = $('header').innerHeight();  //常時取得
        //const headerHeight = $('header.sp').innerHeight() || 0;  //headerに.spを付与してたら取得
        const position = $(hash).offset().top - headerHeight;
        $('html, body').animate({ scrollTop: position }, 500, 'swing');
    }
});

バニラはこう。

window.addEventListener('load', function () {
    const hash = decodeURIComponent(location.hash);
    const target = document.querySelector(hash);

    if (target) {

        //取得しない
        const headerHeight = 0;
        //常時取得
        //const header = document.querySelector('header');
        //const headerHeight = header.offsetHeight;
        //headerに.spを付与してたら取得
        //const header = document.querySelector('header.sp');
        //const headerHeight = header ? header.offsetHeight : 0;

        const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - headerHeight;

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

コメント

タイトルとURLをコピーしました