Event Order in Javascript

While back I came across a very good article explaining about how the event order works in JavaScript. And today I thought to jot the important take away points in this blog. (Also to test how well I understood the concept :). Check the reference section for the source article.

So the question is – What happens if an element and one of its ancestor have an event handler registered for the same event, which one will fire first?

Let say we have elementB inside elementA and both are registered for a onClick event. Now when user clicks on elementB, he will cause the click event in both elementB and elementA. But which event fires first? Which event handler should be executed first? In other words – What is the event order?

Two Models

Back in old days Microsoft and Netscape came up with completely two approaches

  • Microsoft said event on elementB takes place first. This is called event bubbling
  • Netscape said event on elementA takes place first. This is called event capturing

Event Bubbling

If user clicks on elementB, the event handler of elementB fires first and event handler of elementA fires last.

Event Capturing

In case of event capturing, the event handler of elementA fires first and event handler of elementB fires last

W3C Model

In W3C event model any event taking place is first captured until it reaches the target element and then bubbles up again. In this model user can choose whether to register an event handler in the capturing or in the bubbling phase. This is done through by setting the last argument of the addEventListener() method either to true or false. If its set to true, the event handler is set for the capturing phase, if its set to false the event handler is set for the bubbling phase.

Now suppose we do


elementA.addEventListener('click',doSomethingB, true); elementB.addEventListener('click',doSomethingB, flase);

If the user clicks on elementB the following happens:

1) The click event starts in the capturing phase. The event looks if any ancestor element of elementB has a onclick event handler for the capturing phase.
2) The event finds one on elementA. doSomethingA() is executed.
3) The event travels down to the target itself, no more event handlers for the capturing phase are found. The event moves to its bubbling phase and executes doSomethingB(), which is registered to elementB for the bubbling phase.
4) The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase. This is not the case, so nothing happens.

And the reverse would be

elementA.addEventListener('click',doSomethingB, false); elementB.addEventListener('click',doSomethingB, false);

1) The click event starts in the capturing phase. The event looks if any ancestor element of elementB has a onclick event handler for the capturing phase and doesn’t find any.
2) The event travels down to the target itself. The event moves to its bubbling phase and executes doSomethingB(), which is registered to elementB for the bubbling phase.
3) The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase.
4) The event finds one on elementA. Now doSomethingA() is executed.

Reference

a) Quirksmode : Event order