0

Why will the following code show "three" then "two"and then "one" (in this order)? Is it something to do with the function or the table? I was expecting the output to be one, two, three and not the other way around.

<html>
    <head>
        <title>WebDev Exams</title>     
    </head>
    <body>  
        <div id='one'>
            <table>
                <tr id='two'>
                    <td id='three'>Ce1111</td>
                </tr>
            </table>
        </div>
    </body>
    <script type="text/javascript">
        function registerEvent(id) {
            document.getElementById(id).addEventListener('click', function()
            {
                alert(id);
            });
        }
        registerEvent('one');
        registerEvent('two');
        registerEvent('three');
    </script>   
</html>
yuriy636
  • 11,171
  • 5
  • 37
  • 42
Stathis.S
  • 3
  • 4

2 Answers2

0

Default behaviour for addEventListener to listen to event bubbling phase (i.e. from target up the DOM tree). If you want to listen to capture phase you need to pass the third argument to be true.

Docs

target.addEventListener(type, listener[, useCapture]);

function registerEvent(id) {
  document.getElementById(id).addEventListener('click', function() {
    alert(id);
  }, true);
}
registerEvent('one');
registerEvent('two');
registerEvent('three');
<body>
  <div id='one'>
    <table>
      <tr id='two'>
        <td id='three'>Ce1111</td>
      </tr>
    </table>
  </div>
</body>
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
0

DOM Level 3 Events and JavaScript Event order specification allows to register an Event Listener either in the capturing or in the bubbling phase.

But by default, the bubbling phase is used.
It means that the more depth element associated to the listener will be first notified and then the most closest ancestor element of the notified element associated also to this same listener will be notified, and so on...
Whereas the actual behavior.

To use the bubbling phase behavior that has the reverse behavior, you have to specify the second argument (useCapture) of EventTarget.addEventListener() to true. From the official documentation :

useCapture Optional

A Boolean indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. Events that are bubbling upward through the tree will not trigger a listener designated to use capture. Event bubbling and capturing are two ways of propagating events which occur in an element that is nested within another element, when both elements have registered a handle for that event. The event propagation mode determines the order in which elements receive the event

You could so update the method in this way :

function registerEvent(id) {
    document.getElementById(id).addEventListener('click', function()
    {
        alert(id);
    },true);
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215