Event Propagation & Delegation

Event Propagation
The event propagation mode determines the order in which elements receive the event.
Event bubbling and Capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event.
[1]. Bubbling
With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements.
Relate
bubbling
tobubbles in a glass of soda.
[2]. Capturing
With capturing, the event is first captured by the outermost element and propagated to the inner elements.
Syntax :
target.addEventListener(type, listener[, useCapture=false]);target.addEventListener("click", callOnClick);
By default, javascript sets the event propagation to Bubble . If we want to useCapture
we have to set the 3rd argument in the addEventListener function to true
. If NOT specified, useCapture (optional) defaults to false.
The following diagram will give you a further understanding of the event propagation life cycle.

Not all events bubble
The blur
, focus
, load
and unload
events don’t bubble like other events. The blur
and focus
events can actually be accessed using the capturing phase (in browsers other than IE which still hasn’t compromised on adding a capturing phase) instead of the bubbling phase
What do you think its going to happen when i click the box-3 ? Let’s check it out.

If you had an event bound to browser’s Window
, it would be the first to execute. So, in the following example, the order of event handling will be Window
, Document
, DIV 2
, DIV 1
, and finally, the button
.

Omitting or setting the useCapture
argument to ‘false’ inside addEventListener()
will register events for bubbling. So, the default behavior of Event Listeners is to bubble events.

Stop bubbling to outerMost
The method for it is event.stopPropagation()
.
For instance, here body.onclick
doesn’t work if you click on <button>
:

Reference(s):
Event Delegation
https://medium.com/@marjuhirsh/event-propagation-event-delegation-7d3db1baf02a
How JavaScript Event Delegation Works
Event delegation allows you to avoid adding event listeners to specific nodes; instead, the event listener is added to one parent. That event listener analyses bubbled events to find a match on child elements.
Let’s say that we have a parent UL
element with several child elements:
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
Let’s also say that something needs to happen when each child element is clicked. You could add a separate event listener to each individual LI
element, but what if LI
elements are frequently added and removed from the list? Adding and removing event listeners would be a nightmare, especially if addition and removal code is in different places within your app. The better solution is to add an event listener to the parent UL
element. But if you add the event listener to the parent, how will you know which element was clicked?
Here’s a very basic JavaScript snippet which illustrates event delegation:
// Get the element, add a click listener...document.getElementById("parent-list").addEventListener("click", function(e) { // e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
}
});
source: https://javascript.info/bubbling-and-capturing#event-target
event.target
A handler on a parent element can always get the details about where it actually happened.
The most deeply nested element that caused the event is called a target element, accessible as event.target
.
Note the differences from this
(=event.currentTarget
):
event.target
– is the “target” element that initiated the event, it doesn’t change through the bubbling process.this
– is the “current” element, the one that has a currently running handler on it.
For instance, if we have a single handler form.onclick
, then it can “catch” all clicks inside the form. No matter where the click happened, it bubbles up to <form>
and runs the handler.
In form.onclick
handler:
this
(=event.currentTarget
) is the<form>
element, because the handler runs on it.event.target
is the actual element inside the form that was clicked.
NOTE: event delegation is the technique, bubbling is what the event itself does, and capturing is a way of using event delegation on events that don’t bubble.
preventDefault()
The preventDefault() restricts the default action that belongs to the event from occurring. Simply put, preventDefault() cancels the event if it is cancelable.
For example, this can be useful when:
- Clicking on a “Submit” button, prevent it from submitting a form
- Clicking on a link, prevent the link from following the URL
- Clicking on a checkbox, prevents the toggling of the checkbox.
Example:

Toggling a checkbox is the default action of clicking on a checkbox. The preventDefault() method prevents this from happening.
Note:
- Not all events are cancelable. Use the cancelable property to find out if an event is cancelable.
The preventDefault() method does NOT prevent further propagation of an event through the DOM. Use the stopPropagation() method to handle this.