【问题标题】:How to capture pinch-zoom gestures from the trackpad in a desktop browser (and prevent default)?如何在桌面浏览器中从触控板上捕获捏缩放手势(并防止默认)?
【发布时间】:2021-10-18 19:45:20
【问题描述】:

如果您在带有触控板的笔记本电脑上的 Chrome/Firefox 中打开 Google 地图,如果您捏合缩放,它只会缩放地图,而浮动 UI 元素保持静态。所以我知道我想做的事情是可能的。

似乎浏览器不会为桌面浏览器上的触控板触摸发出touch* 事件,但它确实会发出一系列wheel 事件(event.ctrlKey 设置为true ) 用于触控板捏合缩放手势。

问题是,即使使用event.preventDefault(),浏览器仍然总是缩放整个页面。似乎在 wheel 事件上调用 preventDefault() 只会在控制台中打印此警告(Chrome 92):

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312`

(警告中的网址似乎没有任何用处。)

我尝试使用与 Google 地图 (<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">) 相同的元视口标签,但没有帮助。

那么谷歌地图是如何做到的呢?当您在触控板上进行捏合缩放时,它们如何防止默认行为(缩放整个页面)?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我手边没有触控板,但既然你说wheel 事件已被触发,我假设使用鼠标滚轮的上下文是相同的。

    TL;博士

    使用{passive: false} 作为第三个参数调用addEventListener() 即可。

    即:

    window.addEventListener('wheel', function(e) {
    
      e.preventDefault()
      ...
    
    }, {passive: false})
    

    说明

    在addEventListener() 的document 中,passive 选项的描述表明:

    一个布尔值,如果为真,则表明侦听器指定的函数永远不会调用 preventDefault()。如果被动侦听器确实调用了 preventDefault(),则用户代理只会生成控制台警告。

    并根据同一页面中标题为“Improving scrolling performance with passive listeners”的部分:

    根据规范,被动选项的默认值始终为 false。但是,这会导致处理某些触摸事件(以及其他事件)的事件侦听器在尝试处理滚动时阻塞浏览器的主线程,从而导致滚动处理期间的性能可能会大大降低。

    为防止出现此问题,某些浏览器(特别是 Chrome 和 Firefox)已将文档级节点 Window、Document 和 Document.body 上的 touchstart 和 touchmove 事件的被动选项的默认值更改为 true。这样可以防止调用事件侦听器,因此它不会在用户滚动时阻止页面呈现。

    虽然上面这段只提到了touchstart和touchmove事件,但我发现它也适用于Chrome和Firefox中的wheel事件。

    因此,如果您想让preventDefault() 工作,您必须专门将passive 选项设置为false。

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 2018-12-02
      • 2017-08-11
      • 2014-07-04
      • 1970-01-01
      • 2023-02-04
      相关资源
      最近更新 更多