在Chrome的指针锁定期间防止鼠标滚轮事件

时间:2019-01-29 19:38:17

标签: javascript mousewheel pointerlock

如果指针被锁定到某个元素,我想防止鼠标滚轮实际滚动文档。

这是一个最小的示例:

<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()会被忽略,并且页面会上下滚动(不是我想要的)。

示例工作流程可能如下所示:

  1. 我将光标移动到任何地方(是否在div上都没有关系)
  2. 我使用滚轮,页面会相应滚动(应该滚动)
  3. 在控制台中,我看到break
  4. 现在我单击div并且指针已锁定
  5. 控制台显示setting locked: true
  6. 现在我再次滚动,但页面仍滚动(错误
  7. 控制台:locked: true cancelable: false

现在有了一个有趣的部分:如果我从wheel事件监听器中删除了if (!locked) {}部分,则在控制台打印locked: true cancelable: true时实际上会阻止事件

因此出于某种原因,if块使事件不可取消吗?

这是我的问题:我如何有条件地防止鼠标滚轮滚动页面,条件是指针是否锁定到某个元素?

我也尝试过一些事情:

  • 将转轮事件侦听器附加到div
  • 在锁定指针时附加一个无条件阻止的事件侦听器,并在释放锁定时将其删除。
  • 将wheel事件侦听器附加到“所有内容”:window document div ...
  • event.stopPropagation();
  • event.stopImmediatePropagation();(有多少?)

所有结果都与上面的最小示例相同。

编辑:我在 Windows 10 Chromium 65 Google Chrome 71 上尝试了最小示例 CentOS 7.4 :在那里不起作用。

0 个答案:

没有答案