概要
SPメニューを表示した時、スクロールすると後ろの背景ページもスクロールできてしまう問題がある。
一般的に、overflow:hiddenをbodyに当てることで対策するが、1点問題がある。SPメニューを表示したときに、背景ページが一番上までスクロールしてしまう不具合が生じてしまう場合がある。
そのため、本実装をする際は、以下を満足する処理を実装する必要がある。
・背景ページはスクロールできないようにする
・背景ページのスクロール位置はそのままにする
コード
以下コードは既存の処理も含んでいるため一般化はできていないため、太文字部のみ参照のこと。
var $sp_menu = $('.spMenuBtn').closest('.sp_menu');
var scrollPosition = 0;
function noScroll(e) { //eは動作の情報
e.preventDefault(); //「スクロールしていいよ」というブラウザの標準動作を止める命令
window.scrollTo(0, scrollPosition); //元の位置に強制的に戻す。scrollTo(横位置,縦位置)
}
function preventTouch(e) {
if (!$(e.target).closest('#gMenu').length) { //タッチ動作がgMenuの中かどうかを判定
e.preventDefault(); //タッチ動作がgMenuの外(背景部)ならスクロールさせない
}
}
$('body').on('click', '.spMenuBtn', function () {
if ($sp_menu.hasClass('active')) {
document.removeEventListener('wheel', noScroll, { passive: false }); //マウススクロールなどが対象、jsでスクロールを止める
document.removeEventListener('touchmove', preventTouch, { passive: false }); //iphoneの場合に有効、jsでスクロールを止める
}
});
e.preventDefault()とは
eはどんなイベントがどこで起きたかなどのイベントの内容を指す。preventDefaultをつけることで、この標準動作が発生することを防いでいる(preventは「防ぐ」という意味)。
{ passive: false }とは
passiveは何もしないという意味。
{ passive: true }・・・ 正常な状態。js処理は何もしないよ、という状態。
スクロールを止めるjsを書いても、無視されてしまう。
{ passive: false }・・・js処理のために処理を待つよ、という状態。
スクロールを止めるjsの場合、そちらが優先される。
そのため、スクロール処理では必須になる。