Event Delegation - Bubbling and Capturing
Patrice Williams
Posted on January 11, 2021
Events and event delegation are paramount to the functionality of the system or webpage you are programming. Making sure you have a proper understanding of how events work, and when is crucial. I will be discussing event delegation and the facts of it including event bubbling and event capturing.
What are events?
Events are actions that happen in the system you are currently programming in. The system will create a signal once the event occurs, that will provide a mechanism by which actions can automatically be taken when the specific event occurs. So for example, when you are going swimming with a friend, maybe your friend does not want to get into the pool just yet. So you stick your toes in the water to test the temperature. You give the thumbs up signal and you and your friend jump in the pool. The signal was communicated to your friend and now you and your friend can jump in the pool.
So when describing events occurring in a browser window, events are usually attached to a specific item that the window holds (this could be a single element, set of elements, the HTML document that is loaded in the tab you have open, or the whole browser window). Various different events could occur, like an error, the user resizes or closes the browser window, a button is clicked, or the user hovers the cursor over a specific element. Every event that is available has an event handler. An event handler is a block of code (like a JavaScript function that you create) that runs when the event is triggered. Event handlers are sometimes called event listeners, but the two actually work in conjunction. The listener will listen for the event to occur and the handler is the actual code that runs in response to the event happening.
Event Delegation
Bubbling
Event bubbling and capturing are types of event delegation that work together.
Bubbling is when an event occurs on an element, it triggers the handlers first, then its parents are triggered, and all the way up on to the other ancestors. In the following example, we have 3 nested elements with a handler attached to each of them.
<form onclick="alert('Click this FORM!')">FORM
<div onclick="alert('Click this DIV!')">DIV
<p onclick="alert('click this P tag')">P</p>
</div>
</form>
When you click the inner 'p-tag' , it first runs onclick:
- The 'p'
- Then the outer 'div' runs
- Then the outer 'form' runs
- And so on upwards until you have reached the document object.
Stop Bubbling
Most event bubbles, but there are some exceptions (like a focus event). In order to stop a bubbling event, you need to use the method event.stopPropagation(). In the following code example, the body.onclick does not work when clicking the button.
<button onclick="event.stopPropagation()">Click me</button>>
Bubbling can be very convenient, so make sure you really need to stop it before using this method.
Capturing
The last event propagation type that will be discussed is “capturing.” Capturing is generally not used in real code, but can be useful. The standard order of DOM events includes the capturing phase (event happens down to the starting element), target phase (“event reached the target element” (Javascript.info, 2020)), and bubbling phase (event bubbles up from the element). The below picture shows what happens when you click on a
So when 'td' is clicked, the event goes down the ancestors chain to the element (capture phase), then once the target is reached, the event triggers there, and then goes up back up (bubbling phase) and calls handlers along the way.
The below code is an example of capturing and bubbling working together.
<div>
<form>Issa FORM!
<div>DIV tag HOLLER!
<p>P element you already KNOW!</p>
</form>
</div>
<script>
for(let element of document.querySelectorAll('*')) {
element.addEventListener("click", e => alert(`Capturer this coolCat: ${element.tagName}`), true);
element.addEventListener("click", e => alert(`Bubbling is for coolCats: ${element.tagName}`));
};
</script>
</div>
When you click on the 'p' the following occurs:
- HTML then BODY then FORM then DIV (the elements are captured in the following order)
- P is triggered because, now in the target phase, P is triggered two times since we have two listeners: capturing and bubbling
- DIV then FORM then BODY then HTML The code attaches click handlers to every element in the document in order to see which handlers are working. The addEventListener function will run in the same order that they are created.
Conclusion
Event delegation is fundamental to working in JavaScript. It is important to note that when an event occurs, the target element (event.target) is defined as the most nested element when the event happened. As the event moves down the document root to the event.target, calling handlers are assigned. Event bubbling occurs next and the event bubbles up from event.target to the root. In order to stop the event handler, call event.stopPropagation(), but this is not recommended. Make sure you understand event propagation and what bubbling and capturing is so that you can use them successfully in your code.
Sources
MDN. Introduction to Events. Retrieved January 11, 2021, from https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events
Javascript.info.Bubbling and capturing. (2020, October 19). Retrieved January 11, 2021, from https://javascript.info/bubbling-and-capturing
Mainardi, G. (2017, May 23). Event Bubbling in JavaScript? Event Propagation Explained. Retrieved January 11, 2021, from https://www.sitepoint.com/event-bubbling-javascript
Posted on January 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.