このような質問はたくさんあり、多くの答えがありますが、イベント、スクリプト、プラグインなどを含まない満足のいく解決策を見つけることができませんでした.HTML と CSS でそれをまっすぐにしたかった. イベント チェーンを壊すためにマークアップを再構築する必要がありましたが、ようやく機能する解決策を見つけました。
1. 基本問題
モーダル要素に適用されたスクロール入力 (例: マウスホイール) は、祖先要素にスピルオーバーし、そのような要素がスクロール可能である場合、同じ方向にスクロールします。
(すべての例は、デスクトップの解像度で表示することを意図しています)
https://jsfiddle.net/ybkbg26c/5/
HTML:
<div id="parent">
<div id="modal">
This text is pretty long here. Hope fully, we will get some scroll bars.
</div>
</div>
CSS:
#modal {
position: absolute;
height: 100px;
width: 100px;
top: 20%;
left: 20%;
overflow-y: scroll;
}
#parent {
height: 4000px;
}
2.モーダルスクロールに親スクロールがない
祖先がスクロールしてしまう理由は、スクロール イベントがバブルし、チェーンの一部の要素がそれを処理できるためです。これを止める方法は、チェーン上のどの要素もスクロールの処理方法を認識していないことを確認することです。この例では、ツリーをリファクタリングしてモーダルを親要素の外に移動できます。あいまいな理由で、親とモーダル DOM 兄弟を保持するだけでは十分ではありません。親は、新しいスタッキング コンテキストを確立する別の要素でラップする必要があります。親の周りに絶対配置されたラッパーは、そのトリックを行うことができます。
得られる結果は、モーダルがスクロール イベントを受け取る限り、イベントは「親」要素にバブリングしないということです。
通常、エンド ユーザーの表示に影響を与えることなく、この動作をサポートするように DOM ツリーを再設計できるはずです。
https://jsfiddle.net/0bqq31Lv/3/
HTML:
<div id="context">
<div id="parent">
</div>
</div>
<div id="modal">
This text is pretty long here. Hope fully, we will get some scroll bars.
</div>
CSS (新規のみ):
#context {
position: absolute;
overflow-y: scroll;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
3.アップ中はモーダル以外ではスクロールしない
上記の解決策では、スクロール イベントがモーダル ウィンドウによって傍受されない限り (つまり、カーソルがモーダル上にないときにマウスホイールによってトリガーされた場合)、親はスクロール イベントを受け取ることができます。これは望ましくない場合があり、モーダルが起動している間はすべてのバックグラウンド スクロールを禁止したい場合があります。これを行うには、モーダルの背後にあるビューポート全体にまたがる追加のスタック コンテキストを挿入する必要があります。必要に応じて完全に透明にすることができる絶対配置オーバーレイを表示することでこれを行うことができます (しかし ではありませんvisibility:hidden
)。
https://jsfiddle.net/0bqq31Lv/2/
HTML:
<div id="context">
<div id="parent">
</div>
</div>
<div id="overlay">
</div>
<div id="modal">
This text is pretty long here. Hope fully, we will get some scroll bars.
</div>
CSS (#2 の上に追加):
#overlay {
background-color: transparent;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}