DEV Community

Anthony Frehner
Anthony Frehner

Posted on

A closer look at Javascript event listeners & objects

This post isn't meant to be an introduction to Javascript event listeners and the event object; instead it's meant to answer some random questions I had while working on my own event listener system (since I was unable to use domNode.dispatchEvent). --edit-- I just discovered EventTarget! See the section below


If there are multiple event listeners, do they receive the same event object or different objects?

They receive the same event object.

var button = document.createElement('button')

var temp1, temp2

button.addEventListener('click', (evt) => temp1 = evt)

button.addEventListener('click', (evt) => temp2 = evt)

console.log(temp1 === temp2) // true
Enter fullscreen mode Exit fullscreen mode

If an event is preventDefault()-ed, do other listeners still receive that event?

Yes; preventDefault() is a signal that the event's action shouldn't happen, but other listeners will still get called. stopPropagation() and stopImmediatePropagation() is what's used to prevent other listeners from being called. (See questions below)

The Event interface's preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be. The event continues to propagate as usual

MDN Source

If there are multiple event listeners added to the same DOM element, and the first listener calls stopPropagation(), do the other listeners receive the event?

Yes. stopPropagation() prevents the event from bubbling up to higher-up listeners, but it does not prevent listeners from being fired on the same DOM node.

When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.

DOM Standards spec

And that's why stopImmediatePropagation() exists; it will prevent ALL other event listeners from being fired.

Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects.

DOM Standards spec


If you ever think about implementing your own event listener system, you should consider using EventTarget instead! Here's an example:

const target = new EventTarget()

target.addEventListener('myEvent', (evt) => {console.log(evt)})

target.dispatchEvent(new Event('myEvent'))
Enter fullscreen mode Exit fullscreen mode

EventTarget works in all modern browsers and NodeJS >14.5. That's a lot easier than doing it yourself! :)

Discussion (0)