Event Propagation

One thing that many people do not understand about how event processing takes place in JavaScript is propagation. When an event is triggered in JavaScript there may be multiple event listeners that are defined for that event that can be attached to the same tag and/or different tags but where all of those event listeners will react to the event being triggered.

The easiest way to explain how this works is with an example. Since the event listeners are attached to tags within the HTML, let's take a look at the tags used to wrap the content of a supposed web page and look at how a single event trigger can trigger multiple event listeners. We'll examine what will happen when our visitor clicks on the word "click" in this example.

<body class="b1 a5">
<div>
<p></p>
<p></p>
</div>
<div class="b2 a4">
<ul class="b3 a3">
<li><a></a></li>
<li><a></a></li>
<li class="b4 a2"><a class="b5 a1">click</a></li>
</ul>
<p></p>
</div>
<div>
<p></p>
<p></p>
</div>
</body>

Event propagation occurs in two phases. The first phase is the capture phase where the processing starts at the body tag and moves inward toward the location where the event was triggered and the second phase is the bubbling phase where the processing starts at the point where the event was triggered and moves outward until it gets to the body.

The classes attached to the above example indicate the order in which any event listeners attached to those tags will be run. The capture phase will run event handlers in the order b1 through b5 and the bubbling phase will then run event listeners in the order a1 through a5.

Whether an event listener is attached to the capture phase or the bubbling phase is determined by the third parameter. Listeners where the third parameter is true belong to the capture phase while those where it is false or omitted belong to the bubbling phase.

Where two or more listeners are attached to the same tag for the same phase then the standards do not define which order they should run in. Where you have dependent code where the order it runs in matters and it needs to be attached to the same tag then it should all be included in a single event listener. The dependency means that you are not going to be able to add or remove them separately anyway.

With our above example if we were to have ten event listeners attached to the five tags that have classes with one of each belonging to the capture phase and one to the bubbling phase then the order in which those ten will be run is clearly defined and all ten will be run one after the other starting with the capture phase listener on the body and ending with the bubbling phase listener on the body. We can terminate this process at any earlier listener by including a call to stopPropagation() in that listener. When that method is run any subsequent listeners in order that have not yet been run will not be run and the event will be considered to have completed apart from any default action that is associated with the tag where the event was triggered - which you can prevent from occurring using preventDefault().

Note that IE8 and earlier do not support JavaScript. The jScript language they support instead uses attachEvent to attach listeners to the bubbling phase only. It is not possible to attach listeners to the capture phase in those browsers and so any listeners you attach to the capture phase will not be run in IE8 and earlier.

 

This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow
Donate