addEventListener & OptionsaddEventListener() registers an event handler function on a specified DOM target. It supports advanced configuration options such as { once: true }, { passive: true }, and { capture: true }.
flowchart TD
Listener["target.addEventListener(type, handler, options)"] --> OptOnce["once: true -> Automatically removes listener after 1st trigger"]
OptOnce --> OptPassive["passive: true -> Promises handler will NOT call preventDefault() (Smooth Scrolling)"]
OptPassive --> OptCapture["capture: true -> Fires listener during Capturing Phase instead of Bubbling"]
| Option Flag | Type | Default | Explanation |
|---|---|---|---|
once |
boolean |
false |
Listener executes at most once, then removes itself automatically. |
passive |
boolean |
false |
Indicates handler will never call preventDefault(), enabling high-performance scrolling. |
capture |
boolean |
false |
Listens during Capturing Phase instead of Bubbling Phase. |
signal |
AbortSignal |
undefined |
Allows removing the listener via an AbortController. |
// Demonstrating addEventListener options and AbortController cleanup
document.addEventListener("DOMContentLoaded", () => {
const btn = document.createElement("button");
btn.textContent = "Single Click Action";
document.body.appendChild(btn);
// 1. Listener with { once: true }
btn.addEventListener("click", () => {
console.log("This listener executes ONCE and then self-destructs!");
}, { once: true });
// 2. High-Performance Scroll Listener with { passive: true }
window.addEventListener("scroll", () => {
// Passive listener promises never to call event.preventDefault()
// Allows compositor thread to scroll without blocking!
}, { passive: true });
// 3. Cleaning up multiple listeners using AbortController (Modern ES2022)
const controller = new AbortController();
btn.addEventListener("mouseover", () => console.log("Mouseover event"), { signal: controller.signal });
btn.addEventListener("mouseout", () => console.log("Mouseout event"), { signal: controller.signal });
// Detach ALL listeners associated with controller at once!
// controller.abort();
});
{ passive: true } for Touch/Scroll Events: Touch move and wheel listeners should set { passive: true } to prevent UI thread scrolling stutter.removeEventListener(): To remove a listener via removeEventListener(type, fn), fn MUST be a named function reference; anonymous functions cannot be removed.AbortController for Mass Removal: Pass { signal: controller.signal } to group multiple event listeners so a single controller.abort() call unbinds them cleanly.Why can't you remove an anonymous event listener btn.addEventListener("click", () => {}) using removeEventListener?
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.