EventTarget Patterns - Interactive Lab | IconVault

Master CustomEvent, event delegation, and once, passive and signal listener options with live demos. Free, runs in your browser.

All tools

EventTarget Patterns

CustomEvent, delegation, once, passive and signal options

5 of 5 free uses left

CustomEvent with detail

Dispatch a typed custom event; the listener reads event.detail.

custom-event.js
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
delegation.js
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.

once.js
btn.addEventListener("click", handler, { once: true });
// no manual removeEventListener needed

passive: 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()

passive.js
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().

IDLE
signal.js
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.

remove.js
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

addeventlistenerjavascript addeventlistenereventtargetcustomeventjavascript customevent examplecustomevent detaildispatchEventevent delegationevent delegation javascriptevent delegation exampleevent.target vs event.currenttargetevent.target closestonce true addeventlisteneraddeventlistener once optionpassive truepassive event listenerpassive wheel listenerpreventdefault passive ignoredscroll jank passive listenersabortcontroller signal addeventlistenerremoveeventlistenerremove all event listenersabortcontroller remove listenersaddeventlistener optionsaddeventlistener third argumentcapture vs bubble addeventlistenerjavascript event patternsevent listener patternsevent handling best practicesmemory leaks event listenersevent listener cleanupcomponent unmount remove listenerscustom events vs callbacksevent.detail typescriptdispatchevent bubblescomposed custom eventshadow dom custom eventsevent delegation dynamic listevent delegation table rowsdelegation vs direct listenersperformance event delegationtouchstart passivewheel passive listener chromelighthouse passive listenersjavascript event tutoriallearn dom eventsdom events playgroundinteractive events labeventtarget mdnevent listener cheat sheetjs event options explained

More tools

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

View all 10+ tools →