JavaScript + Node.js track

Lesson 19 · Part 5: DOM

Event Handling

`addEventListener`, `preventDefault` and event delegation

Part 5: DOM2 min readFree lesson

Level: Intermediate | Player: 18_DOM_Manipulation

Learning Objectives

  • Change the event handler to addEventListener
  • Read target, type, etc. from the event object.
  • Distinguish between preventDefault and stopPropagation.
  • Reduce the number of handlers by utilizing event delegation.
  • Know the concept of Capture/Bubble steps.

1. addEventListener

btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);

You must pass the same function reference to remove it. Anonymous functions cannot be removed.

2. Event object

The callback receives a Event object.

  • event.target: Element where the event actually occurred
  • event.currentTarget: Element with listener attached
  • event.type: "click", "input", etc.
  • event.key, event.code: Keyboard event

3. preventDefault / stopPropagation

  • preventDefault(): Blocks basic operations (form submission, link movement, etc.).
  • stopPropagation(): Prevent events from propagating to parents.

4. Event delegation

When there are many children, do not register them individually, but process them from one parent.

list.addEventListener("click", (e) => {
  const li = e.target.closest("li");
  if (!li) return;
  console.log("Items clicked:", li.textContent);
});

5. Capture and Bubbles

Events propagate from window → target → parent (capture → bubble). The default is called in the bubble phase, and you can also register the capture phase as addEventListener(type, fn, { capture: true }).

Core example

file Contents covered
index.html Example HTML
01_addeventlistener.js Event Register/Cancel
02_event_object.js Event object properties
03_prevent_default.js Use preventDefault
04_delegation.js Event Delegation

⚠️ Common Mistakes

  1. Problem that only one handler can be registered at a time with onclick = fn.
  2. Register an anonymous function and then attempt to remove it.
  3. Confusion between event.target and event.currentTarget.
  4. When you submit the form, preventDefault is forgotten and the page is refreshed.
  5. There are no events for dynamically added children, so I cannot see a situation where delegation is necessary.

❓ Frequently Asked Questions (FAQ)

Q1. What is the once option? A. { once: true } is executed only once and is automatically released.

Q2. What about passive listeners? A. For scroll performance, if you register as { passive: true }, the preventDefault call will be ignored.

Q3. Is it always good to prevent event propagation? A. Only when absolutely necessary, as it may break other handlers.

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/01_addeventlistener.jsJavaScript
/**
 *Use addEventListener / removeEventListener.
 */
const btn = document.querySelector("#btn");

function onClick() {
  console.log("Button clicked");
}

btn.addEventListener("click", onClick);

//Listener that runs only once
btn.addEventListener("click", () => console.log("Just once!"), { once: true });
src/02_event_object.jsJavaScript
/**
 *Read information from the event object.
 */
const input = document.querySelector("#text");
input.addEventListener("input", (event) => {
  console.log("type:", event.type);
  console.log("target value:", event.target.value);
});
src/03_prevent_default.jsJavaScript
/**
 *Prevent link movement with preventDefault.
 */
const link = document.querySelector("#link");
link.addEventListener("click", (event) => {
  event.preventDefault();
  console.log("Link movement was prevented.");
});
src/04_delegation.jsJavaScript
/**
 *Handle child clicks in one parent (event delegation).
 */
const menu = document.querySelector("#menu");
menu.addEventListener("click", (event) => {
  const li = event.target.closest("li");
  if (!li || !menu.contains(li)) return;
  console.log("Select:", li.textContent);
});
src/index.htmlHTML
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
<title>Event handling</title>
  </head>
  <body>
<button id="btn">Click</button>
<a id="link" href="https://example.com">Link</a>
    <ul id="menu">
<li>Home</li>
<li>Introduction</li>
<li>Contact Information</li>
    </ul>
    <input id="text" type="text" placeholder="input" />

    <script src="01_addeventlistener.js"></script>
    <script src="02_event_object.js"></script>
    <script src="03_prevent_default.js"></script>
    <script src="04_delegation.js"></script>
  </body>
</html>

Assignment

Put 5 items in a list (<ul>) and print the text of the clicked item to the console in a delegated manner.

The reference solution is shown below.

Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

homework_01.htmlHTML
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
<title>Assignment 19-1</title>
  </head>
  <body>
    <ul id="list">
<li>Alpha</li>
<li>Beta</li>
<li>Gamma</li>
<li>Delta</li>
<li>Epsilon</li>
    </ul>
    <script src="homework_01.js"></script>
  </body>
</html>
homework_01.jsJavaScript
/**
 *With delegation, list clicks are handled in one place.
 */
const list = document.querySelector("#list");
list.addEventListener("click", (event) => {
  const li = event.target.closest("li");
  if (!li || !list.contains(li)) return;
  console.log("Click:", li.textContent);
});

Learn this lesson with a mentor

Work through the JavaScript + Node.js track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now