question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for native javascript eventListener.handleEvent()

See original GitHub issue

Hi,

In javascript it is possible to use an Object as eventhandler. See: eventListener.handleEvent() on MDN

listener The object which receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be an object implementing the EventListener interface, or a JavaScript function. See The event listener callback for details on the callback itself.

(Lol, a listener IS an object OR a function… but the first is almost never explained… 🙄)

The great advantage for this that you do not need to use bind(this) etc, because when using an object as listener its context is kept. See this great article on this

But it does not work out-of-the-box here in OL. (Or do I overlook something) Because a listener is called with call() in event/Target.js, and so this native feature breaks.

Of course an OL olObject.on(event, listener) is different then the native javascript event-listener. But I think it would be very nice to have this, and it can be done easily. 🙂

OL has handleEvent() functions in Interactions (and others?). As far as I can see, this will not conflict when the native handleEvent() would be implemented.

Example:

class MyEventHandler{
  _someProp = 'my values';
  handleEvent(e){
    alert(this._someProp);
  }
}

let oHandler = new MyEventHandler();

// initiate some interaction in OL
let oDraw = new Draw(options);
oDraw.on('drawend', oHandler); 

// or on some htmlelement
let oButton = document.getElementById('myButton');
oButton.addEventListener('click',oHandler);

Nicer example

class MyInteractionWrapper{
  _someProp = 'my values';
  _oInteraction;

  handleEvent(e){
    alert(this._someProp);
  }
  constructor(){
    // initiate some interaction in OL
    this._oInteraction = new Draw(options);
    this._oInteraction.on('drawend', this); 
  }
}

let oDraw = new MyInteractionWrapper();

NB!! This ONLY works with addEventListener() and not with properties like object.onevent which only accepts a function. see mdn But OL works only with addEventListener().

At the moment I can get this working, by adding method call(context,e) to the eventHander-object. Like:

  call(context,e){
    // context is NOT used!
    return this.handleEvent(e);
  }

But that is not very nice.

One way to get this working with OL is changing the code in target.js like:

let fnPropagate;
for (let i = 0, ii = listeners.length; i < ii; ++i) {
     if(listeners[i].handleEvent){
        // do not enforce context for that would break the native functionality
	fnPropagate = listeners[i].handleEvent(evt);
     }else{
	fnPropagate = listeners[i].call(this, evt);
     }
     if (fnPropagate === false || evt.propagationStopped) {
         propagate = false;
          break;
     }
}

I do not know if this would create a conflict with the existing handleEvent() functions, but I don’t think so.

I can do a PR, but need some help on getting the typedef right 😬

I really look forward to see your reactions on this. Greetz, flexJoly

PS. I hope the code-examples have no typos, because I did not test these exact examples.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
ahocevarcommented, Mar 10, 2020

@flexjoly In events.js, just add EventListener as type to the ListenerFunction typedef:

/**
 * Listener function. This function is called with an event object as argument.
 * When the function returns `false`, event propagation will stop.
 *
 * @typedef {EventListener|function((Event|import("./events/Event.js").default)): (void|boolean)} ListenerFunction
 * @api
 */
1reaction
ahocevarcommented, Mar 10, 2020

Ok, point taken. Since your suggested change does not add much code or overhead, we’d accept a pull request. Thanks in advance!

Read more comments on GitHub >

github_iconTop Results From Across the Web

EventTarget.addEventListener() - Web APIs | MDN
This must be null , an object with a handleEvent() method, or a JavaScript function. See The event listener callback for details on...
Read more >
Triggering handleEvent() from addEventListener in an es6 ...
I learned yesterday that with addEventListener you can pass an object with a handleEvent() method instead of a callback function and so I...
Read more >
Using handleEvent with React
The EventListener method handleEvent() is called by the user agent when an event is sent to the EventListener , in order to handle...
Read more >
Event Listeners in React Components
You can create an event listener in a React app by using the window.addEventListener method, just like you would in a vanilla Javascript...
Read more >
Introduction to browser events
Here a click runs the function countRabbits() : ... Also addEventListener supports objects as event handlers. In that case the method ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found