Chrome (Opera) 中并非所有车轮事件都可以取消

Not all wheel events are cancelable in Chrome (Opera)

我发现在 Chrome 68 (Opera 55) 中并不是所有的车轮事件都可以取消。例如。有以下代码:

#block {
    width: 10em;
    height: 10em;
    border: 1px solid black;
    overflow: auto;
}

#block div {
    margin: 0.5em;
    padding: 0.5em;
    border: 1px solid blue;
}
<div id="block" onwheel="console.log(event.cancelable)">
        <div>*****</div>
        <div>*****</div>
        <div>*****</div>
        <div>*****</div>
        <div>*****</div>
        <div>*****</div>
</div>

如果您 运行 它并尝试滚动该块,您将看到并非所有事件都是可取消的,也就是说,控制台中有 false 值。

但是,对于 Firefox,所有事件都可以取消。

在我看来,当您取消一系列车轮事件中的第一个事件时,所有后续事件也将被取消。但是我怎样才能知道是否存在一系列事件或只有一个可取消事件?

我需要在用户到达区块底部时更改区块的内容。内容改变后,块自动向上滚动到初始位置,我在内容改变后100毫秒内取消所有事件。但是,在 Chrome 的情况下,我在 second/third 不可取消的滚轮事件发生后更改了内容(因为当用户尚未到达底部时第一个未取消),然后我只是无法取消其他事件,所以块在内容更改后滚动。

有什么解决办法吗? Chrome 的行为是正确的还是只是一个错误?

某些东西可能与 Chrome 71 Beta: relative time formats and more 在 "Async touchpad pinch zoom events" 相关。您可能必须始终调用 preventDefault() 并使用 scrollBy() 来模拟默认行为。

我想出了一个相当直率的解决方案。我仅在滚动事件可取消时才更改块的内容。换句话说,当触发一系列轮子事件时,我只关注可取消事件,如果触发了可取消事件(系列中的第一个事件)并且已经到达块的底部,我会更改块的内容。如果一个事件不可取消,它就会被忽略。

是的,如果几乎到达块的底部,但仍未到达,则存在一种阻塞效果,因为即使用户剧烈滚动滚轮,底部时内容也不会改变到达了。但是,在我看来这不是什么大问题,并且在这种情况下可能会应用优化 - 可能会考虑可取消事件的 deltaY 属性 并且如果它足够大可以将内容滚动到底部,事件可能会被取消,内容可能会以编程方式滚动,然后内容可能会被更改。