Handling Event Propagation In jQuery

Event propagation is an important feature where an event is propagated to its parent control. It is onto that parent control to verify this event if it is coming from its child item and not meant for it, but that is not done automatically and we need to handle it.

Let me simplify it to help you to understand it. Suppose we have a DIV element that has 4 DIVs inside it. Now, we have bound some event to these 4 inner DIVs, let's say the "click" event. Also, we have some requirements and bounded the same "click" event onto our parent DIV.

Let's see the HTML first:

  1. <div id="MainDiv">  
  2.     <div class="childClass" id="ChildDiv1" style="background-color:Green;">      </div>  
  3.     <div class="childClass" id="ChildDiv2" style="background-color:Aqua;">       </div>  
  4.     <div class="childClass" id="ChildDiv3" style="background-color:Black;">      </div>  
  5.     <div class="childClass" id="ChildDiv4" style="background-color:Fuchsia;">    </div>  
  6. </div>  

And this is how we are applying or binding the click event to these elements:

  1. <script type="text/javascript">  
  2.    $(document).ready( function(){  
  3.         $("[id$=MainDiv]").click( function(){ alert('MainDiv');  });  
  4.         $(".childClass").click( function(e){ alert('childDiv');  });  
  5.     });  
  6. </script>  

So, what will be the output? You may be thinking that it is simple; when the user clicks on the child div then only the child div bound event will be triggered. But it gives you two alerts "childDiv" and "MainDiv". Why so? We will understand that using the following picture that demonstrates the region of DIVs.

Just imagine the area of these DIVs. The main DIV is the entire area and inside it there are child DIVs.

Consider the first image. We have bound the "click" event onto the main DIV, so wherever in the entire area of this DIV is clicked, the "click" event will be fired, right?

Now, look at the second image, still we have the Main DIV and its associated "click" event.  Just think about the area of Child DIV1. Isn't it also the area of our Main DIV? Of course it is. So, when you click in the area of Child DIV1, it can be considered that you have also clicked on the area of the Main DIV. Hmm! And that's why we are getting two alerts in our example.

When we bind an event on a control or element, actually a listener is assigned for that event. This listener is not aware of other listeners and works individually. It is their duty to watch for an assigned event on the element and trigger to function call against that event.

 It means we need to look into it and handle the firing of the parent DIV's click event if the Child Div element area is clicked.

Look into these lines:

  1. $("[id$=MainDiv]").click( function(e){ if (e.target == this) alert('MainDiv');  });   

 Another method of handling event propagation is using stopPropagation():

  1. $(".childClass").click(function (e) { alert('childDiv'); e.stopPropagation(); });   

Now, we are checking if the child DIV is really not clicked and if this click event is meant for the Main Div. This will handle our issue and we will get only one alert message in our example. Actually, we are avoiding event propagation by checking event target property and using stopPropagation().

Thus, we can write event binding with avoiding event propagation as in the following:

  1. <script type="text/javascript">  
  2.     $(document).ready( function(){  
  3.         $("[id$=MainDiv]").click(function(e){  
  4.          if (e.target == this)  
  5.             alert('MainDiv');  
  6.           });  
  8.         $(".childClass").click( function(){ alert('childDiv');  });  
  9.      });  
  10. </script>  


  1. <script type="text/javascript">  
  2.     $(document).ready( function(){  
  3.         $("[id$=MainDiv]").click( function(){ alert('MainDiv');  });  
  5.         $(".childClass").click(function (e) {  
  6. alert('childDiv');  
  7. e.stopPropagation();  
  8.           });  
  9.      });  
  10. </script>