DOM Event Bubbling and Capturing

For example:

<div id="parent">
 Hello Parent!
<div id="child">
Child
</div>
</div>
var div = document.getElementById('parent');
var p = document.getElementById('child');
1.
div.addEventListener("click", function(){
 alert('parent'); 
 }, false);
p.addEventListener("click", function(){
 alert('child');
}, false); 
When you click on the child, 'child' will be alerted first in this way, and then alert 'parent', even you don't click on the parent div.

if you bind a click event handler to the parent div, when you click on the child div, it also triggers the handler. This is because of event bubbling.
Event bubbling

          / \
---------------| |-----------------
| element1    | |                |
|  -----------| |-----------     |
| |element2  | |          |     |
| -------------------------     |
|  Event BUBBLING           |
-----------------------------------

the event handler of element2 fires first, the event handler of element1 fires last.

for IE 9+ and other browsers, there are two phase of event processing, one is the above event bubbling, and the other is below event capturing.

Event capturing

          | |
---------------| |-----------------
| element1    | |                |
|  -----------| |-----------     |
| |element2  \ /          |     |
| -------------------------     |
|  Event CAPTURING          |
-----------------------------------

the event handler of element1 fires first, the event handler of element2 fires last.

For attach an event handler, you can decide which phase to trigger the handler by setting a boolean true when you code:

elem.addEventListener( type, handler, true);//event capturing phase to trigger handler
elem.addEventListener( type, handler, false);//default, event bubbling phase to trigger handler
From above example 1, make a boolean change:
div.addEventListener("click", function(){
 alert('parent');
}, true);
p.addEventListener("click", function(){
 alert('child');
}, false);
When you click on the child, 'parent' will be alerted first in this way.

Reference:

http://www.quirksmode.org/js/events_order.html

http://www.quirksmode.org/js/events_order.html

One application of this will be delegation, you handle all the children by listening to the parent for DOM event.

For example, change background of td in a table on click event: (from JS Ninja)

 var cells = document.getElementsByTagName('td');
 for(var n=0;n<cells.length;n++){
   addEvent(cells[n],'click',function(){this.style.backgroundColor='yellow'}); 
 }
 this is a way to bind many event handlers, which is not good. However, you can reduce to
 var table = document.getElementById('table-1');
 addEvent(table,'click',function(e){
  if(e.target.TagName.toLowerCase() == 'td')
     e.target.style.backgroundColor = 'yellow'; 
 });
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s