如何检查侦听器事件是否为被动事件?

How to check if a listener event is a passive event?

我正在编写一个 gesture/action 库,它还管理事件侦听器和触发。我已经实现了我的库来支持通过 API 设置被动侦听器的手势对象,如下所示:this.on('touchstart.passive', this.startHandler, { reject: errorHandler })。我的库支持多种手势,设置多个监听器,有被动的也有非被动的。该库将确保最多只有一个 真实 侦听器将附加到 DOM。所以我们最多可以有2个touchstart个监听器,其中一个是被动的,另一个不是。

我的问题是我无法检测接收到的事件是否附加了 { passive: true } 选项。我认为我可以在本机事件对象上使用 cancelable 属性,因为在被动事件上调用 preventDefault() 是错误的。但是 cancelable 属性 始终为真,即使浏览器会在 preventDefault().

上抛出错误

我已阅读 WhatWG DOM standard on event listeners 并在 Firefox 和 Chrome 中进行了一些测试,但找不到有关如何区分这两种事件的任何信息。

这对我的图书馆很重要,因为被动事件侦听器是用 ".passive" post-fix 键控的,例如"touchstart.passive" 对比 "touchstart".

如何检查收到的 DOM 被动选项事件,以便触发正确的内部侦听器?

编辑

目前我的附加监听器流程的要点是:

function eventNotifier(event) {
    this.fire(event.cancelable ? event.type : event.type + '.passive', new GestureEvent(event))
}

addEvent(el, realEventName, eventNotifier, options)
nativeListeners.set(eventName, 1)

function addEvent (el, type, listener, options) {
    el.addEventListener(type, listener, options || true)
}

其中 nativeListeners 是跟踪真实事件侦听器的 Map

编写一个 if 语句来检查侦听器是否附加了“.passive”。

您可以在调用 event.preventDefault(); 后测试 event.defaultPrevented 的值。如果它是被动事件,浏览器将抛出 warnings/errors 调用,但它不会停止 javascript 的执行。所以以下应该有效:

document.addEventListener('touchstart', function(event) {
  event.preventDefault();
  
  if (event.defaultPrevented) {
    // This is not a passive event
  } else {
    // This is a passive event
  }
}, { passive: true });

我在这个 link 中找到了这个答案的灵感:https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md