如果指针锁定到某个元素,我想防止鼠标滚轮实际滚动文档。
这是一个最小的例子:
<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
块使事件不可取消?
我的问题来了:如何有条件地防止鼠标滚轮滚动页面,条件是指针是否锁定到某个元素?
我也尝试了一些事情:
- 将车轮事件侦听器附加到
div
. - 当指针被锁定时附加一个无条件阻止的事件侦听器,并在释放锁时删除它。
- 将车轮事件侦听器附加到“一切”:
window
document
div
... event.stopPropagation();
event.stopImmediatePropagation();
(那里有多少?)
所有的结果都与上面的最小示例相同。
编辑:我在Windows 10上的Google Chrome 71和CentOS 7.4上的Chromium 65上尝试了最小示例:它在那里不起作用。