[js]動的に生成したアンカー対応のページ内スムーススクロール

何回同じネタ擦ってんだろうね

こう

header分ずらす形で。

$(function(){

    $(document).on('click', 'a[href^="#"]', function (e) {
        e.preventDefault();
        const headerHeight = $('header').innerHeight();
        const speed = 500;
        const href = $(this).attr('href');
        const targetSelector = (href === '#' || href === '') ? 'html' : href;
        const target = $(targetSelector);
        if (target.length) {
            const position = target.offset().top - headerHeight;
            $('html, body').animate({ scrollTop: position }, speed, 'swing');
        }
    });

});

何が違うかといえば、トリガー部分。

普通はこう↓

$('a[href^="#"]').click(function(){

これだと、動的に生成したHTML要素は対象外になる。

それをこう↓

$(document).on('click', 'a[href^="#"]', function(){

こうすることで、jsで動的に生成した<a>、idも対象にできる。

おまけ

動的に生成したIDに外部リンクからアクセスしても対応する内容。

$(function () {
    const headerHeight = $('header').innerHeight();
    const speed = 500;

    function smoothScrollTo(selector) {
        const $target = $(selector);
        if ($target.length) {
            const position = $target.offset().top - headerHeight;
            $('html, body').animate({ scrollTop: position }, speed, 'swing');
        }
    }

    // ページ内リンククリック(動的生成対応)
    $(document).on('click', 'a[href^="#"]', function (e) {
        e.preventDefault();
        const href = $(this).attr('href');
        const selector = (href === '#' || href === '') ? 'html' : href;
        smoothScrollTo(selector);
    });

    // 外部リンクからのアクセス時(動的ID監視)
    const hash = window.location.hash;
    if (hash) {
        const maxWait = 3000; // 最大3秒待つ
        const interval = 100; // チェック間隔

        let elapsed = 0;
        const timer = setInterval(function () {
            if ($(hash).length) {
                smoothScrollTo(hash);
                clearInterval(timer);
            }
            elapsed += interval;
            if (elapsed >= maxWait) {
                clearInterval(timer); // 見つからなければ中止
            }
        }, interval);
    }
});

コメント

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