ポインターが特定の要素にロックされている場合、マウスホイールが実際にドキュメントをスクロールしないようにしたい.
最小限の例を次に示します。
<style>
div {
width: 200px;
height: 2000px;
background: red;
}
</style>
<div></div>
<script>
const div = document.querySelector('div');
let locked = false;
document.addEventListener('pointerlockchange', () => {
locked = document.pointerLockElement !== null;
console.log("setting locked:", locked)
});
div.addEventListener('click', () => {
div.requestPointerLock()
});
document.addEventListener('wheel', event => {
if (!locked) {
console.log("break");
return;
}
console.log("locked:", locked, " cancelable:", event.cancelable);
event.stopImmediatePropagation();
event.preventDefault();
});
</script>
赤い div をクリックすると、ポインターが div にロックされ (これが機能します)、変数locked
が true に設定されます (機能します)。ESC を押すとロックが解除され、マウスを再び動かすことができます (機能します)。
また、マウス ホイール イベントをリッスンし、変数locked
が true に設定されている場合はそれらを防止します。Firefox や Edge でも問題なく動作しますが、Google Chrome ではevent.preventDefault()
無視され、ページが上下にスクロールします (私が望むものではありません)。
サンプル ワークフローは次のようになります。
- カーソルをどこにでも移動します(divの上かどうかは関係ありません)
- スクロールホイールを使用すると、それに応じてページがスクロールします(そうあるべきです)
- 私が見るコンソールで
break
- divをクリックすると、ポインターがロックされます
- コンソールは言う
setting locked: true
- 今、私は再びスクロールしますが、ページはまだスクロールします (間違っています)
- コンソール:
locked: true cancelable: false
ここで興味深い部分がありif (!locked) {}
ます。ホイール イベント リスナーからセクションを削除すると、コンソールに.locked: true cancelable: true
なんらかの理由で、if
ブロックによってイベントがキャンセル不可になるのですか?
ここに私の質問があります:マウスホイールがページをスクロールするのを条件付きで防ぐにはどうすればよいですか?条件は、ポインターが特定の要素にロックされているかどうかです?
私も試したいくつかのこと:
- wheel イベントリスナーを にアタッチし
div
ます。 - ポインターがロックされているときに無条件に防止するイベント リスナーをアタッチし、ロックが解放されたときにそれを削除します。
- wheel イベントリスナーを「すべて」にアタッチする:
window
document
div
... event.stopPropagation();
event.stopImmediatePropagation();
(いくつありますか?)
すべてが上記の最小限の例と同じ結果になりました。
編集: Windows 10のGoogle Chrome 71とCentOS 7.4のChromium 65で最小限の例を試しました:そこでは機能しませんでした。