Event Listener<!-- --> | <!-- -->Yixuan Dai
Javascript source code
Javascript source code by: Markus Spiske
Event Listener

25 07 2021

25 07 2022

JavaScript

Event Listener Basics

Create an Event Listener

const button = document.querySelector("button") button.addEventListener("click", e => { console.log(e) })

The addEventListener can take up to 3 parameters, the third one is optional.

  • The first parameter, here, 'click', specifies the event you’d like to listen to, e.g., mouse click, mouse move..., a complete list of events can be found here.
  • The second parameter is a callback function that has one single argument which is the event argument, commonly called e.
  • Details about the third parameter can be found here.

Remove an Event Listener

  • To remove an event listener, the callback function you pass into removeEventListener should be exactly the same as the one you passed into addEventListener before.
button.addEventListener("click", sayHi) button.removeEventListener("click", sayHi) function sayHi() { console.log("Hi") }
  • Arrow functions won’t work, because they are essentially two different anonymous functions.
button.addEventListener("click", () => { console.log("Hi") }) // this won't work! button.removeEventListener("click", () => { console.log("Hi") })

Event Propagation

Event Bubbling / Capturing

When an event is triggered on an element it will bubble that event up the document tree to all the elements the element is inside of, while the direction is reversed in capturing phase, that is from the top level element to the element we trigged.

An example to setup a capture event listener:

parent.addEventListener("click", () => { console.log("Parent Capture") }, { capture: true })

A great video that explains this: video

Stopping Event Propagation

stopPropagation stops the event from continuing its capturing and bubbling

parent.addEventListener("click", e => { console.log("Parent"); }) child.addEventListener("click", e => { console.log("Child1"); e.stopPropagation(); }) child.addEventListener("click", e => { console.log("Child2"); }) // 'Child 1' and 'Chind 2' will be logged

stopImmediatePropagation will not only stop propagation to the child/parent elements through the bubble and capture phases, but it will also stop other events on the element from triggering as well.

parent.addEventListener("click", e => { console.log("Parent"); }) child.addEventListener("click", e => { console.log("Child1"); e.stopImmediatePropagation(); }) child.addEventListener("click", e => { console.log("Child2"); }) // Only 'Child 1' will be logged

Event Delegation

const buttons = document.querySelectorAll("button") buttons.forEach(button => { button.addEventListener("click", () => { console.log("Clicked Button") }) }) const newButton = document.createElement("button") document.body.append(newButton) // does not have the event listener

The above code shows a common situation that the newly added button won’t have the event listener that we added previously, in this case, we need to manually add an event listener to it, which is less efficient and less easy to manage the event listener, hence, more prone to error. A more elegant and smart way is to use Event Delegation, which sets up the event listener on a parent element, such as the document, example below:

document.addEventListener("click", e => { if (e.target.matches("button")) { (*) console.log("Clicked Button") } }) const newButton = document.createElement("button") document.body.append(newButton)

In the (*) line, we use a if statement to check if the target of the event matches the one we’d like to listen to, so in this case, we can ensure every button even the newly added ones will have the same event listener we’d like to add.

A helper function to use event delegation, from here:

function addGlobalEventListener(type, selector, callback, options) { document.addEventListener(type, e => { if (e.target.matches(selector)) callback(e) }, options) } addGlobalEventListener("click", ".btn", () => { console.log("Clicked Button") }, { once: true })

Reference

https://blog.webdevsimplified.com/2022-01/event-listeners/

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener