Support for native javascript eventListener.handleEvent()
See original GitHub issueHi,
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:
- Created 4 years ago
- Comments:9 (9 by maintainers)
Top GitHub Comments
@flexjoly In events.js, just add
EventListener
as type to the ListenerFunction typedef:Ok, point taken. Since your suggested change does not add much code or overhead, we’d accept a pull request. Thanks in advance!