Skip to main content
JavaScript & the browser·Module C9 · Lesson 8
TaskMake const bus = new EventTarget(). Subscribe to 'order-placed' with a handler that logs 'received: ' + e.detail.id. Dispatch new CustomEvent('order-placed', {detail: {id: 42}}). Then removeEventListener and dispatch again — second one should not log anything new.

EventTarget — your own event bus

125 XP9 min
Theory

The same API DOM elements expose

Every DOM element uses addEventListener / dispatchEvent because they extend EventTarget. You can use EventTarget directly to build a tiny pub/sub bus — no library needed.

const bus = new EventTarget();

bus.addEventListener("user-login", (e) => {
  console.log("welcome", e.detail.name);
});

bus.dispatchEvent(new CustomEvent("user-login", { detail: { name: "Anna" } }));
// "welcome Anna"

CustomEvent

new CustomEvent(name, { detail }) lets you attach an arbitrary payload at event.detail. That's how libraries thread structured data through DOM events.

Why this pattern wins

  • Same shape as DOM events — anyone who knows the browser knows the API.
  • Composable — multiple listeners, removeEventListener, AbortSignal for cleanup.
  • Zero dependencies.

removeEventListener

To stop listening, pass the SAME function reference:

const handler = (e) => console.log(e.detail);
bus.addEventListener("ping", handler);
bus.removeEventListener("ping", handler);

Or use AbortSignal: bus.addEventListener("ping", handler, { signal: ctrl.signal })ctrl.abort() removes the listener.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 10 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.