やりたいこと
- モーダルを表示させているときには、背景となっているコンテンツをスクロールさせないようにする
結論
- どうも完全に制御しきることは難しいという結果になったので、ある程度妥協は必要。要件に応じて以下の解法を使い分けするしかなさそう。
追記(2020/5/23)
今年もこの件でハマって、さらに今回はJQueryではなかったが、この投稿記事の内容よりも、より良い対処があったので記事リンクを追記しました。
解決策
その1.よくある対処法
-
window
のtouchmove
イベントでevent.preventDefault();
する
window/bodyに対する制御だけ。モーダルの表示制御は除外
function openModalScrollControl() {
$("body").addClass("no_scroll");
$(window).on('touchmove', (e) => {
e.preventDefault();
});
// { passive: false } というオプションを付けたら良いかも的な記事もありましたが、
// 付けるとJQuery内部のエラーが頻発する(制御はできてる)のと、オプションを付けなくても同じレベルの制御は出来ていたので、外している
}
function closeModalScrollControl() {
$("body").removeClass("no_scroll");
$(window).off('touchmove');
}
css抜粋
.no_scroll
overflow: hidden
// モーダル最上位要素
.modal_overlay
position: fixed
top: 0
left: 0
bottom: 0
// %が重要、vhだとスクロールが動く
height: 100%
width: 100%
// 重要
overflow-y: auto
// これがないとスクロールがカクカクする。
// fixed + touch でフリーズする問題もあるらしい
-webkit-overflow-scrolling: touch
// モーダルのコンテンツ部分
.modal_contents
...
この方法での問題点
- iphoneブラウザ(safari/chrome)のヘッダー・フッターが隠れる(小さくなる)状態では、
touchmove
で制御できないようなので、背景がスクロールされてしまう-
scroll
イベントに対してpreventDefault
も試したが、ダメだった(当然だろ!ってツッコミは無し)
-
参考リンク
- JSでiOSにも配慮した背景固定なスクロール対応のモーダルウィンドウ
- jQuery スマートフォンでスクロールを停止させたい方へ。
- iOS でページ全体はスクロールを無効にし、個別の要素(textarea など)では有効にする方法
- ipad safari: disable scrolling, and bounce effect?
- jQueryでスマホのスクロールイベントを無効化する
その2.
-
html,body
にoverflow: hidden
を付ける -
overflow: hidden
の影響で表示位置が変わるので、モーダルを閉じたときに、モーダル表示した時の表示位置に戻す
window/bodyに対する制御だけ。モーダルの表示制御は除外
let scrollPos;
export function openModalScrollControl() {
$("html,body").addClass("no_scroll");
scrollPos = $(window).scrollTop();
}
export function closeModalScrollControl() {
$("html,body").removeClass("no_scroll");
$(window).scrollTop(scrollPos);
}
その1と一緒
.no_scroll
overflow: hidden
// モーダル最上位要素
.modal_overlay
position: fixed
top: 0
left: 0
bottom: 0
// %が重要、vhだとスクロールが動かない
height: 100%
width: 100%
// 重要
overflow-y: auto
// これがないとスクロールがカクカクする。
// fixed + touch でフリーズする問題もあるらしい
-webkit-overflow-scrolling: touch
// モーダルのコンテンツ部分
.modal_contents
...
問題点
- モーダルを表示した時
html,body
にoverflow: hidden
を付与する影響で、背景となっているコンテンツのページトップに強制移動しているのが若干わかる(見える)
参考リンク
いつもQiitaには助けられています。感謝