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

7
我正在编写一个手势/动作库,它还可以管理事件监听器和触发。我已经实现了支持手势对象通过API设置被动监听器的库,该API如下所示:this.on('touchstart.passive', this.startHandler, { reject: errorHandler })。我的库支持多个手势、设置多个监听器,包括被动和非被动监听器。该库将确保最多只有一个真正的监听器附加到DOM上。因此,我们最多可以有2个touchstart监听器,其中一个是被动的,另一个不是。
我的问题和困难在于,我无法检测到接收到的事件是否使用了{ passive: true }选项进行附加。我认为可以使用原生事件对象上的cancelable属性,因为在被动事件上调用preventDefault()是错误的。但是,cancelable属性始终为true,即使浏览器在preventDefault()上会抛出错误。
我已经阅读了WhatWG DOM标准上的事件监听器并在Firefox和Chrome中进行了一些测试,但找不到关于如何区分这两种类型事件的任何信息。
对于我的库来说这很重要,因为被动事件监听器是以".passive"后缀为关键字,例如:"touchstart.passive" vs "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,用于跟踪实际事件监听器

2个回答

6

在调用event.preventDefault();后,您可以测试event.defaultPrevented的值。如果是被动事件,浏览器会为此调用抛出警告/错误,但它不会停止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 });

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

1
阅读了您的编辑后,我明白这不是您想要的。您正在寻找一种在事件发生之前确定它是否被动的方法,对吗? - emilchristensen
2
不,你的答案方向是正确的。不过我选择了另外一种方法,因为它更容易实现。我只有两个 eventNotifier。一个用于被动事件,一个用于常规事件。我把被动的 eventNotifierPassive 附加到被动事件上,这样我就不需要测试原生事件了。但如果以下代码可以运行就更好了:addEventListener('wheel', e => { if (e.cancelable) e.preventDefault() }, { passive:true }) 不幸的是,如果存在另一个非被动监听器监听相同的事件名/类型,Chrome 将会将 cancelable 设置为 true。 - dotnetCarpenter

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

1
你的回答在这个情境下没有任何意义。你所建议的是没有标准方法来检测被动事件,我应该重新编写我的架构以某种方式知道一个事件是否被附加了 { passive: true }。这会打破我的单一事件通知器调用路径,但可能是唯一的解决方案。不过我担心你只是凭空提出了一个与你对DOM事件监听器标准或当前浏览器实现知识无关的建议。 - dotnetCarpenter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接