EventTarget Patterns - Interactive Lab | IconVault
Master CustomEvent, event delegation, and once, passive and signal listener options with live demos. Free, runs in your browser.
EventTarget Patterns
CustomEvent, delegation, once, passive and signal options
CustomEvent with detail
Dispatch a typed custom event; the listener reads event.detail.
box.addEventListener("notify", (e) => {
console.log(e.detail); // any structured data
});
box.dispatchEvent(new CustomEvent("notify", {
detail: { user: "ana" },
bubbles: true,
}));Event delegation
One listener on the list handles every item, including ones added later.
- apple
- banana
- cherry
- date
- elderberry
- fig
ul.addEventListener("click", (e) => {
const li = e.target.closest("li[data-fruit]");
if (!li) return; // clicked the gaps
console.log("picked", li.dataset.fruit);
});once: true
The browser removes the listener after the first call. Click the button many times.
btn.addEventListener("click", handler, { once: true });
// no manual removeEventListener neededpassive: true
Scroll inside the box. With passive on, the browser ignores preventDefault() so scrolling never janks.
scrollable line 1: the wheel listener calls preventDefault()
scrollable line 2: the wheel listener calls preventDefault()
scrollable line 3: the wheel listener calls preventDefault()
scrollable line 4: the wheel listener calls preventDefault()
scrollable line 5: the wheel listener calls preventDefault()
scrollable line 6: the wheel listener calls preventDefault()
scrollable line 7: the wheel listener calls preventDefault()
scrollable line 8: the wheel listener calls preventDefault()
scrollable line 9: the wheel listener calls preventDefault()
scrollable line 10: the wheel listener calls preventDefault()
scrollable line 11: the wheel listener calls preventDefault()
scrollable line 12: the wheel listener calls preventDefault()
el.addEventListener("wheel", (e) => {
e.preventDefault(); // silently ignored when passive
}, { passive: true });signal: AbortController
Group listeners under one controller and remove them all with abort().
const ctrl = new AbortController();
el.addEventListener("click", onClick, { signal: ctrl.signal });
// later: removes every listener sharing the signal
ctrl.abort();removeEventListener
The classic toggle: the exact same function reference must be passed to remove it.
function onClick(e) { /* ... */ }
el.addEventListener("click", onClick);
el.removeEventListener("click", onClick); // same reference!Event log
// interact with any demo on the left
5 of 5 free dispatches left.
About this tool
IconVault's EventTarget Patterns lab teaches the essential addEventListener patterns with live, working demos. Dispatch CustomEvent with structured detail, see event delegation handle a whole list with one listener, and try the once, passive and signal options to feel exactly what each one changes. Every interaction is logged to a live event console. It is free and runs fully in your browser.
These patterns are the difference between fragile and robust event code: delegation keeps dynamic lists fast, passive listeners keep scrolling smooth, once removes one-shot handlers automatically, and AbortController signals clean up whole groups of listeners at once. Every snippet is copyable for your projects.
Frequently asked questions
Popular searches
More tools
Algorithm Visualizer
Watch sorting and searching animate step by step
Alt Text Helper
Write better image alt text with live feedback
ARIA Reference
Searchable ARIA roles and attributes guide
Array Visualizer
Step through map, filter, reduce like a debugger
Coming soon
CLI
Coming soon
Figma plugin
Coming soon
VS Code extension
Coming soon
Chrome extension
Coming soon
AI icon generator
Coming soon
Team workspaces
Coming soon