Saturday, January 5, 2013

Event Bubbling and Event Capturing

Preface
Sometimes order of events becomes important. Different browsers behave differently. Precedence of events differs in browsers. Some might handle them in capturing phase and some in bubbling phase or both (W3C model). Precedence makes more sense when you have elements inside one another.

Scenario
We have a table with one cell. There is a combo-box in the cell. Suppose the requirement is to  reverse the order of handlers for onClick and see if we can stop event propagation.

For doing so you can make use of addEventListener method described in W3C Event Capture. This function accepts 3 arguments. Event, handler function and a boolean for capturing/bubbling. First of all we are registering handler when the page load is complete by using onload event.
By passing true to addEventListener we indicate that we are interested in capturing phase and if false
it means we are interested in bubbling phase.
Lets have an example. If you click on the combo, first any ancester is checked for an event handler. Since the capturing phase is set to true, tblBblClicked will be called then since there is no other handlers in capturing phase it will start the bubbling phase and calls comboBblClicked.
You can also turn off all the handlers in the capturing phase by setting both listeners to false.
...
 function comboBblClicked(){  
      alert("combo bbl is clicked");  
 }  
 function tblBblClicked(e){  
      alert("tbl bbl is clicked!");  
 }  
 function registerEventListeners(){  
      var tblBbl = document.getElementById('tblBbl');  
      var comboBbl = document.getElementById('cmbBbl');  
      tblBbl.addEventListener('click',tblBblClicked,true);  
      comboBbl.addEventListener('click',comboBblClicked,false);  
 }  
 </script>  
 </head>  
 <body onload="registerEventListeners();">    
 <table id="tblBbl" border="1" >  
      <tr>  
           <td>  
                <select id="cmbBbl" >  
                     <option value="opt1" >opt1</option>  
                </select>  
           </td>  
      </tr>  
 </table>  
...

Now if you want to stop the propagation of events in one of your event handlers you can make use of
e.stopPropagation() in the W3C model. "e" is the event passed to your handler function.

No comments :