如果您在带有触控板的笔记本电脑上的 Chrome/Firefox 中打开 Google 地图,如果您进行捏缩放,它只会缩放地图,而浮动 UI 元素将保持静态。所以我知道我想做的事情是可能的。
浏览器似乎不会touch*在桌面浏览器上为触控板触摸发出事件,但它确实为触控板捏合缩放手势发出一系列wheel事件(event.ctrlKey设置为)。true
问题是,即使使用event.preventDefault(),浏览器仍然总是缩放整个页面。似乎调用preventDefault()事件wheel只会在控制台中打印此警告(Chrome 92):
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312`
Run Code Online (Sandbox Code Playgroud)
(警告中的 URL 似乎没有任何用处。)
我尝试使用与 Google 地图 ( ) 相同的元视口标签,<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">但没有帮助。
那么谷歌地图是如何做到的呢?当您在触控板上进行捏合缩放时,它们如何防止默认行为(缩放整个页面)?
小智 8
我手边没有触控板,但既然您说wheel事件已发出,我假设使用鼠标滚轮的上下文是相同的。
调用addEventListener()with{passive: false}作为第三个参数就可以了。
即:
window.addEventListener('wheel', function(e) {
e.preventDefault()
...
}, {passive: false})
Run Code Online (Sandbox Code Playgroud)
在addEventListener()的文档中,该选项的描述passive指出:
一个布尔值,如果为 true,则表示侦听器指定的函数永远不会调用 PreventDefault()。如果被动侦听器确实调用了 PreventDefault(),则用户代理除了生成控制台警告之外不会执行任何操作。
根据同一页面中标题为“通过被动侦听器提高滚动性能”的部分:
根据规范,被动选项的默认值始终为 false。但是,这会导致处理某些触摸事件(以及其他事件)的事件侦听器在尝试处理滚动时阻塞浏览器的主线程,从而导致滚动处理期间的性能可能大幅下降。
为了防止此问题,某些浏览器(特别是 Chrome 和 Firefox)已将文档级节点 Window、Document 和 Document.body 上的 touchstart 和 touchmove 事件的被动选项的默认值更改为 true。这可以防止调用事件侦听器,因此在用户滚动时它不会阻止页面渲染。
虽然上面的段落只提到了touchstart和touchmove事件,但我发现它也适用于wheelChrome和Firefox中的事件。
所以如果你想preventDefault()工作,你必须专门将该passive选项设置为false。