Today I Learned - Rocky Kev

TIL using Event Delegation

POSTED ON:

TAGS:

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.

  1. 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:

TIL what is npm Script

Despite their high usage they are not particularly well optimized and add about 400ms of overhead. In this article we were able to bring that down to ~22ms.

TIL fancy methods to transform Javascript Objects

You can use Object.entries(), Object.keys(), Object.fromEntries()...

TIL how to hide your JS code

ONE THING TO NOTE: Encrypting a script is stronger than obfuscation, both methods are still not adequate to protect secret content. Honestly, I don't think it's worth it on a production site, and instead just go with pure server-side if you want security. But it's fascinating.