I often add a bunch of event listeners to things in my sites — a header menu, a sidebar menu, some buttons, some toggles, etc. By the end of a project, there could be a whole bunch of event listeners operating on a page.
I always do this sort of thing:
// all of our menu items
var menuItems = document.querySelectorAll('.primary-nav a');
// loop over them
_.each (menuItems, function(item){
// add event listener to each
item.addEventListener('click', function(){
console.log(item);
});
});
So, on a given site, I might have 4-5 of those kinds of blocks. Is it better to have all these listeners out there, or is it better to listen on the document and employ some kind of class/attribute filtering?
Like so:
document.addEventListener('click', function(e){
if ( e.target.closest('li').classList.contains('primary-nav') ) {
// We have a primary nav item, do something with it
}
if ( e.target.closest('li').classList.contains('mobile-menu-toggle')) {
// function for toggling open the mobile menu
}
});
Advice very welcome!
It depends. Your first example is more performant and only does what you ask it to, in a very clean way. The second example (as others said, it's incomplete - there is no "closest" method) can be more effective if you expect the DOM's structure to change, but don't want to be re-adding event listeners.
If you expect to add a new primary-nav
or mobile-menu-toggle
, then having the one root listener will mean no listeners have to change even when adding/removing elements. Frameworks like JQuery allow for this sort of thing with syntax like this:
$('body').on('click', '.primary-nav', () => {
..
});
Similarly, the listener is added to body
, but only responds to .primary-nav
selector matchers. Keep in mind you should only use this when it makes sense based on the dynamic nature of a page; otherwise the "click" listener will get pretty complicated on a big page.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.