Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm writing a gesture/action library that also manages event listeners and triggering. I have implemented my lib to support gesture objects setting passive listeners via an API that looks like this: this.on('touchstart.passive', this.startHandler, { reject: errorHandler }). My lib supports multiple gestures, setting multiple listeners, both passive and non-passive. The lib will make sure at most only one real listener will be attached to the DOM. So we can at most have 2 touchstart listeners, where one is passive and the other is not.

My question and issue, is that I can not detect if a received event was attached with the { passive: true } option. I thought that I could use the cancelable property on the native event object, since it is an error to call preventDefault() on a passive event. But the cancelable property is always true, even if the browser will throw an error on preventDefault().

I have read the WhatWG DOM standard on event listeners and made some tests in Firefox and Chrome but can't find any information about how to distinguish the two types of events.

It is significant for my library, since a passive event listener is keyed with a ".passive" post-fix, e.g. "touchstart.passive" vs "touchstart".

How to I check the received DOM event for passive option, so I can trigger the right internal listeners?

EDIT

Currently the gist of my flow for attaching listeners is:

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)
}

where nativeListeners is a Map that keep track of real event listeners

like image 681
dotnetCarpenter Avatar asked May 01 '18 19:05

dotnetCarpenter


1 Answers

You can test the value of event.defaultPrevented after the call to event.preventDefault();. The browsers will throw warnings/errors for the call if it is a passive event, however it doesn't halt execution of the javascript. So the following should work:

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

I found the inspiration for this answer in this link: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md

like image 131
emilchristensen Avatar answered Nov 01 '22 07:11

emilchristensen