Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bubbling and capturing with addEventListener

I recently discovered the difference between Bubbling and Capturing on DOM events, using javascript. Now I understand how it's supposed to work, but I've found a weird situation and I would like to know why is that happening.

According to Quirks mode, the event propagation starts with capturing on the outer div, reaches the bottom and then bubbles up to the top. The problem was when I started doing some tests.

On this first one, everything works as expected:

<div id="out">
    <div id="in">
        Click This!!
    </div>
</div>
<script type="text/javascript">
    document.getElementById('out').addEventListener('click', function(){
        alert('capture out');
    }, true);
    document.getElementById('in').addEventListener('click', function(){
        alert('capture in');
    }, true);
    document.getElementById('out').addEventListener('click', function(){
        alert('bubble out');
    }, false);
    document.getElementById('in').addEventListener('click', function(){
        alert('bubble in');
    }, false);
</script>

If you click the text, the alerts go 'capture out', 'capture in', 'bubble in' and 'bubble out'. The problem is using the following code:

<div id="out">
    <div id="in">
        Click This!!
    </div>
</div>
<script type="text/javascript">
    document.getElementById('out').addEventListener('click', function(){
        alert('bubble out');
    }, false);
    document.getElementById('in').addEventListener('click', function(){
        alert('bubble in');
    }, false);
    document.getElementById('out').addEventListener('click', function(){
        alert('capture out');
    }, true);
    document.getElementById('in').addEventListener('click', function(){
        alert('capture in');
    }, true);
</script>

In this case the alerts go 'capture out', 'bubble in', 'capture in' and 'bubble out'. If you notice, the only difference is that on the second one the bubbling is assigned first, but I don't think that should make any difference.

I've tried this with Firefox and Chrome, and the results are the same (I understand that internet explorer doesn't handle capturing).

like image 922
Noel De Martin Avatar asked Jan 28 '12 11:01

Noel De Martin


People also ask

What is the difference between event capturing and event bubbling?

Event capturing means propagation of event is done from ancestor elements to child element in the DOM while event bubbling means propagation is done from child element to ancestor elements in the DOM.

What is bubbling and capturing?

Event bubbling and capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event. The event propagation mode determines in which order the elements receive the event.

What is capture in addEventListener?

With the addEventListener() method you can specify the propagation type by using the "useCapture" parameter: addEventListener(event, function, useCapture); The default value is false, which will use the bubbling propagation, when the value is set to true, the event uses the capturing propagation.

What happens first bubbling or capturing?

With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements. With capturing, the event is first captured by the outermost element and propagated to the inner elements.


1 Answers

quirksmode simplified the model a little. Events in fact go through up to three phases: capturing, at target, and bubbling.

If you log the event.eventPhase like this:

document.getElementById('out').addEventListener('click', function(e){
    console.log(e.eventPhase + " : " + e.target.id + " : bubbling");
}, false);

... you'll see that the 'bubble in' and 'capture in' listeners fire during the AT_TARGET phase. Event listeners invoked for the same element during the same phase are invoked in the registration order.

like image 184
Nickolay Avatar answered Sep 30 '22 00:09

Nickolay