š Event Delegation, the good parts
For a better understanding of how Event Delegation works in JavaScript, it interesting to revisit the basics and understand what events are and how event listeners work. I donāt want to be wordy or deal with it as is rocket science, because itās not, so Iāll summarize in a simple way: Events are things that happen with elements in the DOM (Document Object Model).
To say that events are āthings that happenā sounds a bit too generic, so itās worth giving you some examples of āthings that happenā: an element is clicked, a form is submitted, a text field receives focus, a key is pressed, and a lot more things that donāt need to be exemplified, considering that weāre already aligned about the concept.
For you who are unfamiliar about what is DOM, Iāll also summarize: DOM is a representation of HTML elements, as objects, in a tree structure, to be accessed and manipulated.
Well, if events are āthings that happenā, what are event listeners? I hate being obvious, but the very name of the phenomenon does not allow me not to be: event listeners are statements that listen to things that happen. If buttons could talk, this statement would be something like āOops, Iām a button in the DOM and Iām going to stay here, just waiting to be clicked.ā But, along as they canāt, we can use JS and it would have more or less this aspect:
Soā¦ What the f*ck is Event Delegation?
Imagine that we have a few elements that should be listened in a similar way. Instead of writing a listener for each of them to handle it when an event occurs, Event Delegation allows us to declare the listener in a parent element common to those elements we want to manipulate. And this implementation is possible thanks to the capturing and bubbling concepts, that make up what we are calling as Event Delegation.
It may not have been clear just with this limited explanation, so letās start with an example. Consider this list of links:
Every time someone clicks on one of these links, it should have its text changed. One way (bad way) to do this is to declare a listener for each element in that list. Something like that:
Now, imagine that this list is dynamic. Thus, new items can be added, or items that exist can be removed. But, declared listeners only handle list elements that already existed at the time of declaration. How to solve this?
When an event is triggered on an element in the DOM, itās triggered in sequence through the ancestor elements of the original element that had the event triggered. This effect is known as bubbling, just because, itās as if the event were bubbling through the elements nesting where the event was fired. In our link list example, the click event happens on element a and is then propagated to the element li, then to the element ul, and so on throughout the DOM tree.
āOkay man, this really isnāt rocket science, but how do you use it in a practical way?ā You might be wondering.
There are two properties that reference the target elements of a triggered event, in the declared listener. Pay attention, because they are easy to confuse, since its semantics are not good. They are target and currentTarget.
The target property refers to the exact element the event was fired. So, from this element, the event will be propagated (bubbling, remember?) to the ancestor elements, in a bottom up way, through the DOM tree.
The currentTarget property will always refer to the element that the event listener was declared. Always. Sempre. Siempre. Immer. Ī Ī¬Ī½ĻĪ±. ēø½ęÆ.
Knowing this, we can use this effect to improve the listening to the events we wrote above. Check it out:
Note that the listener is declared in the parent element of who we really want to manipulate. Within the handler (the event callback, which receives the triggered event as a parameter), we use a conditional to ensure that the code snippet only executes when the target is the element we want to manipulate. If we want to make sure that the ul element is actually manipulated, we should use the currentTarget, which would not need the conditional, considering that it ALWAYS refers to the element that the listener was attached. Note also that instead of 4 static listeners, we have only 1 listener that has the same effect and supports a dynamism in the elements. It doesnāt matter if new items are added to that link list, the event listener will continue to have the desired effect.
Pretty cool, huh?!
. . .
Maybe youāre asking yourself āOkay, he talked about bubbling, but he also said something about capturing.What is that?ā. Capturing is the process where event propagation happens from the most ancestral element to the most specific element in the DOM. Briefly, itās as if it were in the opposite direction of bubbling. Being more specific, events are processed in two steps. In the first stage, capturing happens, the propagation goes from the most ancestral element to the most specific one and in the second stage bubbling happens, which we have already studied well up to now.
Thatās all, folks! I hope Iāve been able to help someone by simplifying the concepts behind events delegation.
Um abraƧo. š¤