もっと詳しく

アンカーポイントがずれてしまう

ハッシュタグを使用してアンカーの位置にジャンプしようとしたとき、LazyloadやSlick.jsなどのSliderを使っているせいか、画像表示ページが伸縮するために、意図する位置で表示されないことが起こりました。

具体的には画像スライダーのあるページに<form>でお問合せフォームを設置していて、actionには自らのページにハッシュタグを付けており、submitで送信後に戻ってきたときにスクロール位置がずれました。しかも、パソコンとスマホ(iPhone)で停まる位置が異なり、ブラウザを変えてもの同じ挙動でした。そこで、以下のソースで解決できました。jQueryが必要です。

解決できたソース

URLに#contactなどハッシュタグが含まれていた場合、ページ上部からアンカーまでの位置を取得し、数秒後に画面が伸縮した後に再度、アンカーのポジションを確認して比較します。もし、比較して変化があればその位置に画面をスクロールさせます。

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
//
//Lazyloadなどでアンカーの高さが変化する場合の対応
//
$(window).ready(function() {
try {
    const deleyTime = 600; //アンカー位置を再確認するまでの待機時間(マイクロ秒)
    const adjust = 50; //高さの微調整
    
    //URLに#タグがあるか確認
    const getHash = ($this) => {
        if (!location.hash){
            console.log('アンカータグは指定されていません。');
        } else {
            return location.hash;
        }
    }
    console.log('アンカータグは '+getHash()+' です。');

    //アンカーの位置確認(1回目)
    const firstPositionY = $(getHash()).offset().top;
    console.log('最初に取得した '+getHash()+' の高さは '+firstPositionY+' です。');

    //アンカーの位置確認(2回目)
    const secondPositionY = ($this) => {
       return $(getHash()).offset().top;
    }

    //数秒後にアンカーの位置が変わっていたら正しい位置にスクロール
    setTimeout(function(){
        console.log(deleyTime/1000+'秒後の '+getHash()+' の高さは '+secondPositionY()+' です。');
        if(firstPositionY != secondPositionY()){
            $('html,body').animate({ scrollTop: secondPositionY()+adjust }, 'fast');
            console.log(getHash()+' の現在位置が変化しているため正しい位置にスクロールしました。')
        }else{
            console.log(getHash()+' の現在位置に変化はありません。')
        }
    }
    ,deleyTime);
} catch (error) {
    console.log('アンカータグが見当たらないため処理を終了しました。');
}
});
</script>

 

以下の部分の最後にある'fast''slow''nomal'にするとスクロールのスピードが変わります。

$('html,body').animate({ scrollTop: secondPositionY()+adjust }, 'fast');