I want to prevent the mouse wheel from actually scrolling the document if the pointer is locked to a certain element.
Here is a minimal example:
<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>
When I click the red div the pointer is locked to the div (this works) and the variable locked
is set to true (works). When I press ESC the lock is released and I can move the mouse again (works).
I also listen for mouse wheel events and prevent them if the variable locked
is set to true. On Firefox and even Edge this works fine but on Google Chrome the event.preventDefault()
is ignored and the page scrolls down/up (not what I want).
A sample workflow might look like this:
- I move the cursor anywhere (over the div or not doesn't matter)
- I use the scroll wheel and the page scrolls accordingly (as it should)
- In the console I see
break
- Now I click on the div and the pointer is locked
- The console says
setting locked: true
- Now I scroll again, but the page still scrolls (wrong)
- Console:
locked: true cancelable: false
Now comes the interesting part: If I remove the if (!locked) {}
section from the wheel event listener, the event is actually prevented while the console prints locked: true cancelable: true
.
So for some reason the if
block makes the event non-cancelable?
Here comes my question: How can I conditionally prevent the mouse wheel from scrolling the page, with the condition being whether the pointer is locked to a certain element?
Some things I also tried:
- Attaching the wheel event listener to the
div
. - Attaching an unconditionally preventing event listener when the pointer is locked and removing it when the lock is released.
- Attaching the wheel event listener to "everything":
window
document
div
... event.stopPropagation();
event.stopImmediatePropagation();
(how many are there?)
All had the same outcome as the minimal example above.
Edit: I tried the minimal example on Google Chrome 71 on Windows 10 and on Chromium 65 on CentOS 7.4: It didn't work there.