<div id="binding-every-element"> <button>[1].addEventListener</button> <button>[2].addEventListener</button> <button>[3].addEventListener</button> </div>
// Commonly seen in the wild // Grab the parent, loop through children, add event listeners to each. var binding_events_container = document.getElementById('binding-every-element'); var binding_events_buttons = binding_events_container.getElementsByTagName('button'); for ( var i = 0, len = binding_events_buttons.length; i < len; i++ ){ var button = binding_events_buttons[i]; button.addEventListener('click', function(event){ its.a(event.target); }); }
Disadvangages:
new_element.addEventListener('click', sameFunction);
// Other elements are intentionally nested here. <div id="event-delegation"> <button>Event Delegation Button 1</button> <button>Event Delegation Button 2</button> <button>Event Delegation Button 3</button> <div>Keep in mind - this isnt a button</div> <div style="border:1px solid red"> <button>And this div has a button inside - and this button also has an event</button> </div> </div>
// Event Delegation // The event propagates throughout the children elements // One event, all future elements. var event_delegation_container = document.getElementById('event-delegation'); event_delegation_container.addEventListener('click', function(e){ its.a(e.target); });
With Event Delegation, any element inside the container will receive the event.
We can also write conditional logic to capture specific elements with event.target.nodeName
event_delegation_container.addEventListener('click', function(event){ // Only button elements will do this if ( event.target.nodeName === 'BUTTON' ){ its.a(event.target); } });
<div id="switch-container"> <button data-navigation="home">Home</button> <button data-navigation="about">About</button> <button data-navigation="other">Other things</button> <input data-navigation="input" type="button" value="this is an input type=button - not a BUTTON"></input> </div>
var switch_container = document.getElementById('switch-container'); function myOrganizedEvents(event){ // Get the data-attribute "data-navigation" value from the button clicked var navigation_data = event.target.getAttribute('data-navigation'); // Switch is like a bunch of else if's switch(navigation_data) { case 'home': // Run home specific functions its.a('homeTemplate() - navigation_data = ' + navigation_data, false); break; case 'about': // Run about specific functions its.a('aboutTemplate() - navigation_data = ' + navigation_data, false); break; case 'other': // Run other specific functions its.a('otherTemplate() - navigation_data = ' + navigation_data, false); break; default: // A nice little message to self if nothing matches console.log('data-navigation action not found'); break; } } // Event Delegation Binding events on parent container switch_container.addEventListener('click', function(event){ // Check if the element is a button if ( event.target.nodeName === 'BUTTON' ){ // Run my event organization distribution function myOrganizedEvents(event); } });
I like organizing events with data-attributes and distrubting them through a switch statement.
Cleaner than a conditional soup, and organized in one place which is nice.