Event Bubbling & Capturing

 

Let's talk about interesting topic Event bubbling & capturing in JavaScript. If you never heard about this, then now you are going to get this right now right away ;)

 
Event Bubbling up
 
DOM elements can be nested, and clicking on inner (child) element will invoke handler of parent element. This is called bubbling up. 
 
Event Bubble up Example 1
  • List 1
  • List 2
  • List 3
/**
As you can see here, even clicking on "<li>" child element,
parent element's "<ul>" handler (i.e. onclick event get fired) 
also getting called.
*/
<ul onclick="alert('<ul> clicked')">
	<li onclick="alert('<li> clicked')"> List 1 </li>
	<li onclick="alert('<li> clicked')"> List 2 </li>
	<li onclick="alert('<li> clicked')"> List 3 </li>
</ul>

 

This is happening because an event bubbles up from nested (child) element and triggers the parent element handlers. You can think of event bubbling is like ripple effect when you drop an object in water (you can see ripple effect in below image). The event gets triggered from inner towards outer element.

 

 

Let's visualize this with another example.

 

Event Bubble up Example 2
    • List 1
    • List 2
    • List 3
/**
So when you click on inner li element, 
the handler of outer elements are also getting called.
And the order of execution will be like this if you click 
on any of the li : three->two->one
*/
<html>
<head>
	<title>Event Bubbling Example</title>
	<link rel="stylesheet" type="text/css" href="eventbubble.css">
</head>
<body>
<ul class="one" onclick="changeColor(this)">
  <ul class="two" onclick="changeColor(this)">
	<li class="three" onclick="changeColor(this)">
		List 1
	</li>
	 <li class="three" onclick="changeColor(this)">
		List 2
	 </li>
	 <li class="three" onclick="changeColor(this)">
		List 3
	 </li>
   </ul>
 </ul>
</body>
</html>
<script >
function changeColor(_this){
	_this.style.backgroundColor = 'Chartreuse';
	alert(_this.className);
	_this.style.backgroundColor = '';
}
</script>

 


 

Capturing
 
So What is Capturing? The event first goes down is called capturing phase, and then bubble up.
As per the above example (Example 2) Execution order will be as below for Capturing and bubbling up.
 
Capturing phase: one->two->three
Bubble up phase: three->two->one
 
You can enable event capturing only by passing last parameter as true (phase) to addEventListener method (i.e element.addEventListener(type, handler, phase);)

phase = true : handler is set on the capturing phase.
phase = false: handler is set on bubbling phase.
 
Target vs this
 
target is going to be the same originating element (i.e. the element where you have performed any event). this is current element, it changes in context of current element. Let's understand this by example, I am taking the same example 2.
 
 
Target vs this Example
    • List 1
    • List 2
    • List 3
/**
So if you see here target element is not changing (it's consistent) and 
this is changing as per the current element handler execution.
*/
<html>
<head>
	<title>Event Bubbling Example</title>
	<link rel="stylesheet" type="text/css" href="eventbubble.css">
</head>
<body>
<ul class="one" onclick="changeColorWithEvnt(this, event)">
  <ul class="two" onclick="changeColorWithEvnt(this, event)">
	<li class="three" onclick="changeColorWithEvnt(this, event)">
		List 1
	</li>
	 <li class="three" onclick="changeColorWithEvnt(this, event)">
		List 2
	 </li>
	 <li class="three" onclick="changeColorWithEvnt(this, event)">
		List 3
	 </li>
   </ul>
 </ul>
</body>
</html>
<script >
function changeColorWithEvnt(_this, event){
	_this.style.backgroundColor = 'Chartreuse';
	alert("This: "+_this.className);
	alert("Target: "+event.target.className);
	_this.style.backgroundColor = '';
}
</script>

 


 

Stop Bubbling up
 
You can stop event bubbling simply by calling event.stopPropagation() method. For IE < 9 it is event.cancelBubble = true.
Let's take the same example again.
 
 
Cancel Bubble up
    • List 1
    • List 2
    • List 3
/**
So if you see here target element is not changing (it's consistent) and 
this is changing as per the current element handler execution.
*/
<html>
<head>
	<title>Event Bubbling Example</title>
	<link rel="stylesheet" type="text/css" href="eventbubble.css">
</head>
<body>
<ul class="one" onclick="cancelBubbleup(this, event)">
  <ul class="two" onclick="cancelBubbleup(this, event)">
	<li class="three" onclick="cancelBubbleup(this, event)">
		List 1
	</li>
	 <li class="three" onclick="cancelBubbleup(this, event)">
		List 2
	 </li>
	 <li class="three" onclick="cancelBubbleup(this, event)">
		List 3
	 </li>
   </ul>
 </ul>
</body>
</html>
<script >
function cancelBubbleup(_this, event){
	event.stopPropagation(); // this cancel the bubble up event.
	_this.style.backgroundColor = 'Chartreuse';
	alert("This: "+_this.className);
	alert("Target: "+event.target.className);
	_this.style.backgroundColor = '';
}
</script>

 

Hope you have got fare understanding of Event Bubbling and Capturing in JavaScript.
 
 
Keep Reading and Keep Learning.