Event Handling

📖 Concept

Events are actions that happen in the browser — clicks, keypresses, form submissions, scrolling, etc. JavaScript can listen for and respond to these events.

Adding listeners: element.addEventListener(event, handler) Removing listeners: element.removeEventListener(event, handler) (must use same function reference!) Event Object: Contains info about the event — target, type, preventDefault(), stopPropagation()

Event Propagation has 3 phases:

  1. Capturing — Event travels from window down to the target
  2. Target — Event reaches the target element
  3. Bubbling — Event bubbles back up from target to window

Event Delegation — Attach ONE listener to a parent to handle events from children. Efficient and works for dynamically added elements!

🏠 Real-world analogy: Event bubbling is like yelling in a building — the sound starts in your room (target), then the hallway hears it (parent), then the floor, then the whole building. Event delegation is having ONE security guard at the entrance instead of one per room.

💻 Code Example

codeTap to expand ⛶
1// Basic event listener
2const button = document.querySelector("#myBtn");
3button.addEventListener("click", function(event) {
4 console.log("Clicked!", event.target);
5});
6
7// Arrow function listener
8button.addEventListener("click", (e) => {
9 e.preventDefault(); // Prevent default behavior
10 console.log("Button text:", e.target.textContent);
11});
12
13// Event delegation — handle all list item clicks from parent
14const list = document.querySelector("#todoList");
15list.addEventListener("click", (e) => {
16 if (e.target.matches("li")) {
17 e.target.classList.toggle("done");
18 }
19 if (e.target.matches(".delete-btn")) {
20 e.target.parentElement.remove();
21 }
22});
23
24// Event propagation
25document.querySelector(".outer").addEventListener("click", () => {
26 console.log("Outer (bubble)");
27});
28document.querySelector(".inner").addEventListener("click", (e) => {
29 console.log("Inner");
30 e.stopPropagation(); // Stop bubbling
31});
32
33// Capturing phase (third argument = true)
34document.querySelector(".outer").addEventListener("click", () => {
35 console.log("Outer (capture)");
36}, true);
37
38// Once: automatically removes after first trigger
39button.addEventListener("click", () => {
40 console.log("This fires only once!");
41}, { once: true });
42
43// Keyboard events
44document.addEventListener("keydown", (e) => {
45 if (e.key === "Enter" && e.ctrlKey) {
46 console.log("Ctrl+Enter pressed!");
47 }
48});
49
50// Custom events
51const customEvent = new CustomEvent("userLoggedIn", {
52 detail: { username: "Alice", role: "admin" }
53});
54document.dispatchEvent(customEvent);
55document.addEventListener("userLoggedIn", (e) => {
56 console.log("User:", e.detail.username);
57});

🏋️ Practice Exercise

Mini Exercise:

  1. Build a keyboard shortcut listener (e.g., Ctrl+S to save)
  2. Implement event delegation for a dynamic list (add/remove items)
  3. Create a drag-and-drop interface using mouse events
  4. Build a form with real-time validation using input/blur events

⚠️ Common Mistakes

  • Using anonymous functions with removeEventListener — you need the SAME function reference to remove it

  • Forgetting preventDefault() on form submit — the page will reload!

  • Attaching listeners inside loops without delegation — creates many listeners instead of one

  • Confusing event.target (actual clicked element) with event.currentTarget (element the listener is on)

  • Not understanding that stopPropagation() stops bubbling but preventDefault() stops the default action — they are different!

💼 Interview Questions

🎤 Mock Interview

Mock interview is powered by AI for Event Handling. Login to unlock this feature.