Event bubbling and capturing in JavaScript.
Event bubbling and capturing are two ways of event propagation in the DOM tree.
PermalinkEvent Bubbling
In the bubbling, the event is "bubbled" up to the DOM tree. so from the targeted element to its parent elements and finally to the root.
Let's check with an example
<div id="ceo">
CEO
<div id="manager">
manager
<div id="developer">
developer
</div>
</div>
</div>
Here is the execution flow for bubbling. A click on Developer: Developer -> Manager -> CEO
A click on Manager: Manager -> CEO
A click on CEO: CEO
The process is called “bubbling” because events “bubble” from the inner element up through parents like a bubble in the water.
PermalinkEvent capturing
In the capturing the event starts from the root then go down the tree and stops at the target element. Event capturing is also called event trickling.
Let's check with an example
<div id="ceo">
CEO
<div id="manager">
manager
<div id="developer">
developer
</div>
</div>
</div>
Here is the execution flow for capturing. A click on Developer: CEO -> Manager -> Developer
A click on Manager: CEO -> Manager
A click on CEO: CEO
PermalinkThe flow of events is
1 Event capturing
2 Event target
3 Event bubbling
By default, event bubbling will execute if want to enable capturing then add true in addEventListener as the third argument.
addEventListener('click', () => {}, true);
PermalinkHow to stop propagating further
To stop events from further execution we have to use the stopPropagation method. so execution will stop from that point
even.stopPropagation();
PermalinkBubbling example with variations
HTML
<div id="ceo">
CEO
<div id="manager">
manager
<div id="developer">
developer
</div>
</div>
</div>
JS
document.querySelector('#ceo").addEventListener('click', () => {
console.log("CEO clicked")
});
document.querySelector("#manager").addEventListener('click', () => {
console.log("Manager clicked")
});
document.querySelector('#developer").addEventListener('click', () => {
console.log("Developer clicked")
});
Onclick of developer
output
Developer clicked
Manager clicked
CEO clicked
Onclick of manager
output
Developer clicked
Manager clicked
CEO clicked
PermalinkCapturing examples with variations
JS
document.querySelector('#ceo").addEventListener('click', () => {
console.log("CEO clicked")
}, true);
document.querySelector("#manager").addEventListener('click', () => {
console.log("Manager clicked")
}, true);
document.querySelector('#developer").addEventListener('click', () => {
console.log("Developer clicked")
}, true);
Onclick of developer
output
CEO clicked
Manager Clicked
Developer Clicked
Onclick of Manager
output
CEO clicked
Manager Clicked
Permalinkexample with a mix of capturing, bubbling and stop propagation.
JS
document.querySelector('#ceo").addEventListener('click', () => {
console.log("CEO clicked")
}, true);
document.querySelector("#manager").addEventListener('click', () => {
console.log("Manager clicked")
}, false);
document.querySelector('#developer").addEventListener('click', () => {
console.log("Developer clicked")
}, true);
onClick of developer
output
CEO clicked
Developer clicked
Manager clicked
Here as CEO and Developer execute because they are capturing
and then bubbling
starts to execute. (capturing -> target -> bubbling)
JS
document.querySelector('#ceo").addEventListener('click', () => {
console.log("CEO clicked")
}, false);
document.querySelector("#manager").addEventListener('click', (e) => {
console.log("Manager clicked")
e.stopPropagation();
}, false);
document.querySelector('#developer").addEventListener('click', () => {
console.log("Developer clicked")
}, false);
onClick developer
output
Developer clicked
Manager clicked
Here due to stop propagation event will stop execution after the manager clicks.
JS
document.querySelector('#ceo").addEventListener('click', () => {
console.log("CEO clicked")
e.stopPropagation();
}, true);
document.querySelector("#manager").addEventListener('click', (e) => {
console.log("Manager clicked")
}, true);
document.querySelector('#developer").addEventListener('click', () => {
console.log("Developer clicked")
}, true);
onClick developer
output
CEO clicked
as this is capturing it starts from ceo
but due to stop propagation will stop further execution.