TIL using Event Delegation
POSTED ON:
TAGS: javascript events
When you have to dynamically generate a list of links, it's common to think about looping through your list and assigning them a individual event.
Something like this:
<ul id="dogs">
<li><a href="#dog1">Dog1</a></li>
<li><a href="#dog2">Dog2</a></li>
<li><a href="#dog3">Dog3</a></li>
<li><a href="#dog4">Dog4</a></li>
<li><a href="#dog5">Dog5</a></li>
<li><a href="#dog6">Dog6</a></li>
<li><a href="#dog7">Dog7</a></li>
<li><a href="#dog8">Dog8</a></li>
<li><a href="#dog9">Dog9</a></li>
<li><a href="#dog10">Dog10</a></li>
</ul>
<script>
const linkClicked = (element , link) => {
console.log(link);
output.innerHTML = link.innerHTML;
element.preventDefault();
};
const assignHandlers = element => {
let links = document.querySelectorAll(`${element} a`);
links.forEach(link => {
link.addEventListener('click', element => {linkClicked(element,link)});
});
}
assignHandlers('#dogs');
</script>
Great idea, right?
Well well well.
Check this out: https://codepo8.github.io/talks-back-to-basics/event-handling.html
When you click on "Toggle More Dogs", the links break.
This is why we use Event Delegation. (write that down!)
The benefits are:
1 - There are less event handlers to setup and reside in memory.
2 - There's no need to re-attach handlers after a DOM update. If your page content is generated dynamically (say via rest apis) you don't need to add and remove event handlers as elements are loaded or unloaded.
So rather than loop through every item, you instead want to have one event listener on the parent, that runs through a if-statement.
- It's *cheaper for the browser to track one event and fire it on every click that it is to manage multiple events.
document.querySelector('#dogs')
.addEventListener('click', element => {
let target = element.target;
// if the target has a link, do this
if (target.href) {
console.log(target.innerText); // f.e. "Dog5"
output.innerHTML = target.innerText;
}
// if the target is just a list item, do this
if (target.nodeName === 'LI') {
// print out the link
console.log(target.innerHTML);
output.innerHTML = target.innerHTML;
}
e.preventDefault(); // Don't follow the links
});
Back to Basics: Event Delegation
Related TILs
Tagged: javascript