One of my recent tasks was - to implement the site side menu list (using vanilla javascript), and I was very glad to take a challenge - and practice my vanilla skills. I like to use vanilla - since I think it will replace in short future all the frameworks like react & angular...
Yes it sad (because I big fun of frameworks) but lets face the truth - javascript (or ECMASCRIPT) is developing very fast and already doing most of things we needed frameworks for...
Lets Focus, The Menu
So, menu is the very simple one, with links to all site subpages, but the goal is - that clicks on items should be handled only by javascript
<ul class="menu">
<li><a href="javascript: void(0)">1 menu</a></li>
<li><a href="javascript: void(0)">2 menu</a></li>
<li><a href="javascript: void(0)">3 menu</a></li>
</ul>
For simplicity sake - lets say that "handle" means - to print the textContent of clicked item to the console.First Try
So my first solution was to capture all the 'a' elements using "querySelectorAll" native method, and attach listeners to each of the using "forEach" loop:
document.querySelectorAll('ul.menu a')
.forEach(menuItem => menuItem.addEventListener('click', ({target}) => {
console.log(target.textContent); // printing '1 menu' when first menu clicked
}))
Second Look
After giving the code a second look - I suddenly figured out the things may be done much more simply - by attaching the listener only to parent 'ul' element:
document.querySelector('ul.menu').addEventListener('click', ({target}) => {
console.log(target.textContent)
})
The advantage (except from simplicity) of this attitude is that instead of many listeners we using only one (which is much more performant)
Conclusion
The main reason we can use only one listener for many elements is the advantage of using "target" - the way to identify the element user clicked inside the parent element. The important thing here - is to know that event argument has also "currentTarget" property, and unlike "target"(which set to element the user actually clicked upon) - the "currentTarget" set to element the listener attached to