JavaScript Event Delegation

Better event listeners

Event listeners on each button

    <div id="binding-every-element">
    // 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){


  1. Slower to bind events
  2. If any new items are added:
    new_element.addEventListener('click', sameFunction);

Adding one event listener to the parent

Keep in mind - this isn't a button
    // 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>
    // 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){

With Event Delegation, any element inside the container will receive the event.

We can also write conditional logic to capture specific elements with

    event_delegation_container.addEventListener('click', function(event){
      // Only button elements will do this
      if ( === 'BUTTON' ){

Organizing events with switch and data-attributes

    <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>
    var switch_container = document.getElementById('switch-container');

    function myOrganizedEvents(event){
      // Get the data-attribute "data-navigation" value from the button clicked
      var navigation_data ='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);

        case 'about':
          // Run about specific functions
          its.a('aboutTemplate() - navigation_data = ' + navigation_data, false);
        case 'other':
          // Run other specific functions
          its.a('otherTemplate() - navigation_data = ' + navigation_data, false);

          // A nice little message to self if nothing matches
          console.log('data-navigation action not found');

    // Event Delegation Binding events on parent container
    switch_container.addEventListener('click', function(event){
      // Check if the element is a button
      if ( === 'BUTTON' ){
        // Run my event organization distribution function

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.