Episode 1 — Fundamentals / 1.15 — Event Handling in JavaScript
1.15.a — addEventListener, Bubbling & event.target
In one sentence:
addEventListenerregisters a function that runs when an event fires; the event walks the DOM (capture → target → bubble), andevent.targettells you which element the user actually interacted with.
Navigation: ← 1.15 Overview · 1.15.b — Mouse, Keyboard, Scroll & Strict Mode →
1. addEventListener(type, listener, options?)
const btn = document.querySelector("#save");
btn.addEventListener("click", (event) => {
console.log("clicked", event.type);
});
| Part | Meaning |
|---|---|
type | String: "click", "input", "keydown", … |
listener | Function (or object with handleEvent) invoked when the event fires |
| Third arg | Legacy: useCapture boolean. Modern: options object |
Options (common):
| Option | Effect |
|---|---|
capture: true | Run listener in capture phase (outer → inner) instead of default bubble phase |
once: true | Auto-remove after first invocation |
passive: true | Promise you will not call preventDefault() — helps scroll performance (see 1.15.e) |
2. Removing a listener: same function reference
function onClick(e) {
console.log(e);
}
btn.addEventListener("click", onClick);
btn.removeEventListener("click", onClick);
removeEventListener must receive the same function reference and the same capture flag. Anonymous arrows cannot be removed unless you keep a reference.
3. Event flow: capture → target → bubble
Capture phase: window → … → parent → target
Target phase: on the target element
Bubble phase: target → parent → … → window (default listener phase)
By default, your listener runs in the bubble phase (after the target handles the event, then ancestors). Set { capture: true } to run earlier, on the way down.
4. Bubbling vs non-bubbling (awareness)
Most DOM events bubble (click, input, change, keydown…). Some do not (focus / blur without delegation tricks, scroll on elements — varies; load on window does not bubble like a DOM click). For interviews: know click bubbles.
5. event.target vs event.currentTarget
| Property | Meaning |
|---|---|
event.target | The innermost element that originated the event (e.g. the <span> inside a <button> you clicked) |
event.currentTarget | The element this listener is attached to (often equals this in non-arrow classic functions — avoid relying on this; use currentTarget) |
Delegation pattern: attach one listener on <ul>; use event.target to see which <li> was clicked.
6. stopPropagation() vs preventDefault()
| Method | What it stops |
|---|---|
event.stopPropagation() | Event climbing (or continuing in capture) — parent listeners may not run |
event.preventDefault() | Browser’s default action (follow link, submit form, scroll) — only when allowed for that event type |
They are independent — use the one that matches your goal.
7. Key takeaways
addEventListeneris the standard way to react to user and browser events.- Bubbling lets you listen on ancestors and inspect
event.target. target≠currentTarget— critical for event delegation.
Explain-It Challenge
Explain without notes:
- Why does
removeEventListenerfail if you pass a new anonymous function? - If a listener is on
<div id="box">but the user clicks a<span>inside it, what aretargetandcurrentTarget? - What is the difference between
stopPropagationandpreventDefault?
Navigation: ← 1.15 Overview · 1.15.b — Mouse, Keyboard, Scroll & Strict Mode →