JavaScript  

🧠 What is Event Bubbling?

You're sitting inside a small room (a <button>), which is inside a bigger room (a <div>), which is inside an even bigger hall (<body>).

Now, someone knocks on the innermost room's door (you click the button ). That knock doesn’t just stop there — it echoes outward to the next room, then the next, all the way out.

That’s what event bubbling is in JavaScript.

When an event happens on an element, it first runs the handlers on that element, then on its parent, then all the way up to the document root.

Example

<div id="box">
  <button id="btn">Click Me</button>
</div>
document.getElementById("btn").addEventListener("click", function () {
  console.log("Button clicked");
});

document.getElementById("box").addEventListener("click", function () {
  console.log("Box clicked");
});

When you click the button, both events will run:

Button clicked
Box clicked

Because the event bubbles up from the button to the box.

🧨 What is Event Capturing?

Now imagine the opposite:

The knock starts from the outermost hall and goes inward — the big hall hears it first, then the middle room, then finally the innermost room.

That’s event capturing.

It's the reverse of bubbling. It starts from the top (like window or document) and trickles down to the target element.

But by default, JavaScript doesn’t use the capturing phase unless you tell it to.

How to Use Capturing?

element.addEventListener("click", handler, true);

If we update our earlier example:

document.getElementById("btn").addEventListener("click", function () {
  console.log("Button clicked");
}, false); // bubbling

document.getElementById("box").addEventListener("click", function () {
  console.log("Box clicked");
}, true); // capturing

Now the output becomes:

Box clicked
Button clicked

Because the box heard it first during the capturing phase, then the button during bubbling.

🔄 Three Phases of Event Propagation

Every event goes through three phases :

  1. Capturing Phase: From window down to the parent elements.
  2. Target Phase: The actual element that was clicked.
  3. Bubbling Phase: From the clicked element back up to window.

But when you add an event listener, you can only choose between capturing or bubbling , not both.

🛑 How to Stop Event Bubbling?

Sometimes you don’t want the event to go up to the parent.

Like, if you have a delete icon inside a card, and clicking delete shouldn’t also trigger the card click.

Use

event.stopPropagation();

Example

document.getElementById("deleteBtn").addEventListener("click", function (e) {
  e.stopPropagation();
  alert("Delete clicked!");
});

Now the card won’t think it was clicked.

❌ Difference Between stopPropagation() and preventDefault()

Method What It Does
stopPropagation() Stops the event from going up to the parents
preventDefault() Stops the default behavior (like link navigation or form submit)

Example:

document.querySelector("a").addEventListener("click", function (e) {
  e.preventDefault(); // stops page jump
  console.log("Link clicked but not opened");
});

🎯 Real-World Use Cases

Let’s see where these concepts are used practically.

✅ 1. Dropdown Close on Outside Click

You have a dropdown menu. When the user clicks anywhere outside the dropdown, it should close.

document.addEventListener("click", function (e) {
  if (!dropdown.contains(e.target)) {
    dropdown.classList.add("hidden");
  }
});

This works because of event bubbling — every click eventually reaches the document.

✅ 2. Form Validation Using Delegation

You have a form with multiple fields. Instead of adding listeners to each field, you add one to the form and let the event bubble.

form.addEventListener("input", function (e) {
  if (e.target.matches(".required")) {
    validateField(e.target);
  }
});

This makes your code cleaner and more efficient.

✅ 3. Nested Buttons or Icons

You have a card with a delete button. Clicking delete shouldn't open the card details.

deleteIcon.addEventListener("click", function (e) {
  e.stopPropagation();
  removeItem();
});

This prevents the card click handler from running.

✅ 4. Logging User Actions

You can track user actions at a high level instead of attaching listeners everywhere.

document.body.addEventListener("click", function (e) {
  console.log("User clicked:", e.target.tagName);
});

🧪 Interview Questions & Answers

Here are some common interview questions you might get — and how to answer them without sounding like a robot.

Q 1. What is Event Bubbling?

Ans

Event bubbling means that when an event happens on an element, it first runs the handler on that element, then bubbles up to its parent, and so on until it reaches the document root.

Q 2. What is Event Capturing?

Ans

Event capturing is the opposite of bubbling. The event starts at the outermost element (like window) and flows inward to the target element.

Q 3. How do you stop an event from bubbling?

Ans

Using event.stopPropagation().

Q 4. What is the difference between stopPropagation and preventDefault?

Ans

  • stopPropagation: Stops the event from reaching parent elements.

  • preventDefault: Stops the browser’s default action (like submitting a form or following a link).

Q 5. When would you use the capturing phase?

Ans

Rarely. But sometimes, when you want to intercept events before they reach the target, like for global logging or access control.

Q 6. Can you have both bubbling and capturing for the same event?

Ans

Yes, if you attach two different listeners on the same element — one in the capturing phase (true) and one in bubbling phase (false).

✅ Summary Table

Concept Description
Event Bubbling Runs from child to parent
Event Capturing Runs from parent to child (useCapture: true)
stopPropagation Stops the event from moving up/down
preventDefault Stops the default browser action
Real Use Case Dropdown close, form validation, nested buttons
Interview Tip Know how the event flows and when to stop it

So yeah, Event Bubbling and Capturing might sound complex, but once you understand how events flow, it’s super useful for building smarter, more efficient apps.