Javascript Event Listeners
- Overview
- Handling the event callback
- Event Bubbling and Capturing
- Remove event listeners (TBD)
- Delegate events (TBD)
- Examples
- Additional Resources
Overview
element.addEventListener('event', eventHandler);
-
element
: is the HTML element to which you want to attach the click event listener. The HTML element can be selected using one of the many DOM selector elements. -
event
: is the name of the event to listen for. ('click', 'submit', 'keydown', etc) -
eventHandler
: is a callback function that will be executed when the click event occurs. The eventHandler takes a single parameter which is the event object commonly denoted ase
.
element.addEventListener('event', e => { });
Handling the event callback
The eventHandler or callback, takes a single parameter which is the event object commonly denoted
as e
.
This event object gives different kinds of info. For example, where your mouse is, the screen size, and a whole lot more.
One of the most important items is the target. The target
is essentially the he 'thing' or
'element' the event happened on.
<div class="app"></div>
const theTarget = document.querySelector('.app');
theTarget.addEventListener('event', e => console.log(e.target));
// outputs: <div class="app"></div>
Event Bubbling and Capturing
The short version
- Bubbling goes from the target element up to the root of the DOM hierarchy.
- Capturing, also known as 'trickling' goes from the root down to the target element.
Bubbling
Event bubbling is the default behavior in which an event starts from the target element that triggered it and then "bubbles up" through its parent elements in the DOM hierarchy. This means that the innermost element's event is triggered first, followed by its parent, and then its parent's parent, and so on, up to the top-level element (usually the document).
const grandparent = document.querySelector('.grandparent');
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');
grandparent.addEventListener('click', (e) => console.log(`Grandparent clicked`));
parent.addEventListener('click', (e) => console.log(`Parent clicked`));
child.addEventListener('click', (e) => console.log('Child clicked'));
In this example, clicking the grandparent
<div>
triggers only the event associated with the
grandparent. Clicking the parent
<div>
triggers events for both the grandparent
and
parent
. And, as you might expect, clicking the child
<div>
triggers events for all three:
grandparent
, parent
, and child
.
Capturing
Event capturing (also known as Trickling) is the opposite of bubbling. It involves the event starting from the top-level element and "trickling down" through the nested elements to the target element that originally triggered the event.
Capturing is handled by passing a third parameter (options) to the event listener:
element.addEventListener('event', eventHandler, {capture: true});
const grandparent = document.querySelector('.grandparent');
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');
grandparent.addEventListener('click', (e) => console.log(`Grandparent capture`), { capture: true });
parent.addEventListener('click', (e) => console.log(`Parent capture`), { capture: true });
child.addEventListener('click', (e) => { console.log('Child capture') }, { capture: true });
grandparent.addEventListener('click', (e) => console.log(`Grandparent bubble`));
parent.addEventListener('click', (e) => console.log(`Parent bubble`));
child.addEventListener('click', (e) => console.log('Child bubble'));
// Grandparent capture
// Parent capture
// Child capture
// Child bubble
// Parent bubble
// Grandparent bubble
Stop propagation (TBD)
Fire and event only once (TBD)
Remove event listeners (TBD)
Delegate events (TBD)
Examples
Run a function on click
element.addEventListener('click', functionName);
Add class on click
document.querySelector('.btn').addEventListener('click', () => {
// Add your desired class name here (e.g., "new-class")
const classNameToAdd = 'green';
// Get the first element with the class "bx"
const bxElement = document.querySelector('.bx');
// Check if the element already has the class
const hasClass = bxElement.classList.contains(classNameToAdd);
// If the element does not have the class, add it; otherwise, remove it
if (!hasClass) {
bxElement.classList.add(classNameToAdd);
} else {
bxElement.classList.remove(classNameToAdd);
}
});
function eventHandler(event) {
if (event.type === "fullscreenchange") {
/* handle a full screen toggle */
} else {
/* handle a full screen toggle error */
}
}