Learning Objectives
- Create events with
new CustomEvent(type, { detail })and fire them withdispatchEvent - Namespace event names (
timer:start) to keep them out of the browser's way - Route several related events through one listener function
- Recognize the publish/subscribe pattern — components that announce instead of being polled
Mint, dispatch, listen
Three moving parts. A CustomEvent carries a type name you choose, plus an optional detail payload — any data the listener should receive. dispatchEvent fires it at an element. And addEventListener works on your type names exactly as it does on 'click':
The timer: prefix is a convention, not a requirement — but a good one. Namespaced names cannot collide with a current or future browser event, and they read as a vocabulary: everything the timer can say starts with timer:.
One router, one place for state
Three events could mean three separate handlers, each poking at the UI. The demo routes all three through one function instead, and that function is the single place where status text and button-state choreography live:
Read the whole file and notice the shape: buttons announce (“start was requested, at this timestamp”), the router reacts. The button code knows nothing about which controls get disabled; the router knows nothing about which click produced the event. That separation is the entire point.
Open the console while you press the buttons — each event's detail payload is logged there.
Why this pattern matters
The alternative to announcing is polling — some other piece of code checking, on a timer or on every render, whether the timer's state changed. Events invert that: interested parties subscribe, and are called exactly when there is news. You have seen this pattern from the consuming side all series; now you own both ends.
<simple-timer>), and that is no accident: a well-built web component communicates outward by dispatching custom events, never by reaching into the page around it. When you get to the Web Components series, this step is the vocabulary lesson for it. And since custom events bubble only if you ask (bubbles: true), a component can choose whether its announcements stay local or travel up the tree to delegated listeners — the flow rules from Step 3 apply to your events too.Next Steps
Custom events fire when you say so. Some built-in events fire far more often than you can afford to handle. In Step 7: Taming the storm:
- Meet the firehose events:
scroll,pointermove,resize, rapidinput - Throttle a handler to at most once per interval
- Debounce a handler to run only after the input goes quiet