2022年09月06日

[jQuery]
jQueryのscrollTop()が正常に動かない件

どこまでスクロールさせたか、またスクロール位置を指定することもできるjQueryのscrollTop()ですが、過去の納品物に正常に動作していないものがあったので調査しました。

ハンバーガーメニューを開いたときに、背面の本文部分を固定する

もともと、スマホのハンバーガーメニューを開いた際、本文部分をロックさせたいと考えて以下のように設定していました。

body.fixed {
    position: fixed;
    width: 100%;
    height: 100%;
}
var pos;
$('.hamburger-menu').on('click', function(){
    if(!$(this).hasClass('active')){
        pos = $(window).scrollTop();
        $('body').addClass('fixed').css({'top': -pos});
        $(this).addClass('active');
    } else {
        $('body').removeClass('fixed').css({'top': 0});
        window.scrollTo( 0 , pos );
        $(this).removeClass('active');
   }
});

ネットで探すとこんなコードが多いのではないかと思います。
ハンバーガーメニューボタンにhamburger-menuというクラスを付けておいて、クリックされたとき、(2行目)
activeというクラスが付いていなかったら(3行目)
現在のスクロール位置を保存して(4行目)
bodyタグにfixedクラスを付け(固定する)、座標を現在の位置に指定する(先頭に移動してしまうため)(5行目)
そして、hamburger-menuにactiveというクラスをつける(6行目)
もし、ハンバーガーメニューボタンをクリックしたときにactiveクラスがあったら(7行目)
bodyタグに付いているfixedクラスを外し、先頭を0に(8行目)
保存していた現在位置に移動させる(9行目)
そしてhamburger-menuにあるactiveというクラスを外す(10行目)
という流れになります。
実際には、activeクラスが付いたらメニューを開くとか、そういう処理が入ってくることになります。

ところが、以前納品していたこの部分「ハンバーガーメニューがクリックされたら現在位置を保存する」
pos = $(window).scrollTop();
の部分が、どうしても0になってしまうという問題がありました。
なので、ハンバーガーメニューをクリックすると必ず先頭位置になってしまう、ということで原因を漁りました。

bodyにoverflow:hiddenを指定していると駄目とか、同じくbodyにwidthとheightは100%を指定すると駄目とか色々原因があがっているのですが、以前は正常に動いていたので違う問題。
その中で、こちらの方の記事

を発見しました。
実際のchromeのアップデート記事

を確認しても、該当記事がないので真偽の程は確かではありませんが、たしかにChromeでは先頭に移動してしまい、Firefoxでは問題ないのでこれが原因か、ということで試してみました。

var pos;
$('.hamburger-menu').on('click', function(){
    if(!$(this).hasClass('active')){
        if ('scrollingElement' in document) {
            pos = document.scrollingElement.scrollTop;
        } else {
            pos = document.body.scrollTop;
        }
        $('body').addClass('fixed').css({'top': -pos});
        $(this).addClass('active');
    } else {
        $('body').removeClass('fixed').css({'top': 0});
        window.scrollTo( 0 , pos );
        $(this).removeClass('active');
   }
});

こちらで正常に動作するようになりました。

まとめ

リファレンスにあるのに動作しないって困りますよね。
あまりネットにもこの情報は載っていないようなので何とかしてほしいものです。
ちなみに、scrollTop()には、その位置に移動させる機能もありますが、そちらはChromeでも動作するようです。

この記事を書いた人

おおつき@TTI

Webディレクター、Webコンサルタント、Webコーダー、日曜プログラマー、他色々やってます。

気になったら
まずはご相談を

あなたの悩みのために専門家がチームを組み、課題解決に取り組みます。
まずはお気軽にお問い合わせください。

日本全国どこでも対応します。