かんろぐ Written by kan

スムーススクロールで別ページに飛んでも特定の位置まで正しくスクロールさせる方法

CODE HTML/CSS

PR ※当サイトではアフィリエイト広告を利用しています

「別ページに遷移した時のスムーススクロールがうまくいかない、、なぜか高さの位置がずれてしまう、、」

別ページに遷移した時のスムーススクロールがうまくいく方法を解説します。

あるあるなのですが、スムーススクロールを実装する時によく見るソースコードというのは、同一ページであれば、問題なく動くのですが、他ページ遷移する場合にはうまくいかないケースがよくあります。

例えば、フッターに配置されているリンクと言うのは、ページ単位だけでなく、◯◯ページの途中のセクション部分だったりします。
「企業情報」ページに「社長メッセージ」「会社概要」「沿革」「事業拠点」と、同一ページの中のセクションをリンクとしてフッターに記載するケースがよくあります。

このように、別ページの途中のセクションに飛ばしたい時に、通常のスムーススクロールの実装だとうまくいかずに高さがずれてしまうことがしばしばあります。

今回はそれを解決します。

基本的なスムーススクロールの記事はこちら

スムーススクロールを別ページに飛んでも特定の位置まで正しくスクロールさせる方法

それでは順番にHTMLとJavaScriptを見ていきます。

HTML

HTMLは書き方だけちょっと注意が必要です。

まずは飛ばしたい位置(ここではセクション)に下記のコードを記述します。
設定としては、Aboutページのセクション◯◯の位置といった部分です。

<section data-id="#test" id="test" class="test">

ポイントは、data-id="#xxx" と追加して記述しているところです。
また同一ページでも遷移ができるように、id=”test”と、通常用のスムーススクロールの記述も記載しています。

次に、リンクタグの方を見ていきます。
aタグに記述するのですが、ここでは先ほどの遷移先のページを「about」とします。
つまり、フッターなどに

<a href="/about/#test">Aboutページのセクションテストに飛ばしたい</a>

上記のように、/xxxx/#test と記述すればOKです。

これでHTMLは完了です。

JavaScript

$(function() {
    let pageHash = window.location.hash;
    if (pageHash) {
        let scrollToElement = $('[data-id="' + pageHash + '"]');
        if (!scrollToElement.length) return;
        $(window).on('load', function() {
            history.replaceState('', '', './');
            let locationOffset = scrollToElement.offset().top;
            let navigationBarHeight = $('.header').innerHeight();
            locationOffset = locationOffset - navigationBarHeight - 65;
            $('html, body').animate({
                scrollTop: locationOffset
            }, 300, 'swing');
        });
    }
});

$(function() {
    $('a[href*="#"]').on('click', function() {
        const scrollSpeed = 400;
        const navigationHeight = $(".header").innerHeight();
        const scrollToTarget = $(this.hash === '#' || '' ? 'html' : this.hash)
        if (!scrollToTarget.length) return;
        const scrollPosition = scrollToTarget.offset().top - navigationHeight - 105;
        $('html, body').animate({
            scrollTop: scrollPosition
        }, scrollSpeed, 'swing');
        return false;
    });
});

あとは上記のソースコードをJSに貼り付けます。

これで同一ページだけでなく、他ページからの遷移であっても特定の高さの位置に進むことが可能です。

スムーススクロールの解説

それぞれ解説をします。

$(function() {
    let pageHash = window.location.hash;
    if (pageHash) {
        let scrollToElement = $('[data-id="' + pageHash + '"]');
        if (!scrollToElement.length) return;
        $(window).on('load', function() {
            history.replaceState('', '', './');
            let locationOffset = scrollToElement.offset().top;
            let navigationBarHeight = $('.header').innerHeight();
            locationOffset = locationOffset - navigationBarHeight - 65; //ここはそれぞれの高さに変更してください。
            $('html, body').animate({
                scrollTop: locationOffset
            }, 300, 'swing');
        });
    }
});

このJavaScriptはページロード時に、URLのハッシュ(#に続く部分)を取得し、そのハッシュがある場合に特定の操作を行います。

ハッシュがデータ属性(data-id)と一致する要素を取得し、その要素が存在する場合、ページの一部へのスクロールアニメーションを設定します。

ヘッダーの高さと追加の65ピクセルを引いた位置へスクロールします。これにより、目標となる要素がヘッダーに隠れることを防いでいます。

$(function() {
    $('a[href*="#"]').on('click', function() {
        const scrollSpeed = 400;
        const navigationHeight = $(".header").innerHeight();
        const scrollToTarget = $(this.hash === '#' || '' ? 'html' : this.hash)
        if (!scrollToTarget.length) return;
        const scrollPosition = scrollToTarget.offset().top - navigationHeight - 105;//ここも調整してください。
        $('html, body').animate({
            scrollTop: scrollPosition
        }, scrollSpeed, 'swing');
        return false;
    });
});

こちらはページ内リンク(#を含むリンク)がクリックされたときに動作します。

クリックされたリンクのハッシュを取得し、そのハッシュに対応する要素(またはハッシュが存在しない場合はページ全体)へスクロールします。

ヘッダーの高さと追加の105ピクセルを引いた位置へスクロールし、同様に要素がヘッダーに隠れることを防いでいます。

まとめ

別ページに遷移した時のスムーススクロールがうまくいく方法を解説しました。

スムーススクロールは便利ですが、結構盲点だったりもします。
実際の案件で2日ほどわからず詰みました。少しでも助けになれば幸いです。

以上になります。

他にも記事を見てみる

この記事を書いた人
かんろぐ/プロフィールアイコン
かん
未経験からWeb制作会社へ転職 | Webの楽しさや転職のあれこれを発信 | 転職サポート「CodeChange」主催 / 転職成功15名超 | WordPress・Shopify | CodeBegin転職講師 | マナブさん弟子 | カオマンガイとサウナ | ブロガー | ●かんろぐ運営/月間7,600PV達成 |

合わせて読みたい記事