Event delegation

Event delegation allows us to attach a single event listener to a parent element. This event will fire for all the descendants matching a selector even if these descendants will be created in the future (after the listener was bound to the element).

We discussed event bubbling earlier. Event delegation in jQuery works primarily due to event bubbling. Whenever an event occurs on a page, the event bubbles up from the element that it originated from, up to its parent, then up to the parent's parent, and so on, until it reaches the root element (window). Consider the following example:

<html>
  <body>
    <div id="container">
      <ul id="list">
        <li><a href="http://google.com">Google</a></li>
        <li><a href="http://myntra.com">Myntra</a></li>
        <li><a href="http://bing.com">Bing</a></li>
      </ul>
    </div>
  </body>
</html>

Now let's say that we want to perform some common action on any of the URL clicks. We can add an event handler to all the a elements in the list as follows:

$( "#list a" ).on( "click", function( event ) {
  console.log( $( this ).text() );
});

This works perfectly fine, but this code has a minor bug. What will happen if there is an additional URL added to the list as a result of some dynamic action? Let's say that we have an Add button that adds new URLs to this list. So, if the new list item is added with a new URL, the earlier event handler will not be attached to it. For example, if the following link is added to the list dynamically, clicking on it will not trigger the handler that we just added:

<li><a href="http://yahoo.com">Yahoo</a></li>

This is because such events are registered only when the on() method is called. In this case, as this new element did not exist when .on() was called, it does not get the event handler. With our understanding of event bubbling, we can visualize how the event will travel up the DOM tree. When any of the URLs are clicked on, the travel will be as follows:

a(click)->li->ul#list->div#container->body->html->root

We can create a delegated event as follows:

$( "#list" ).on( "click", "a", function( event ) {
  console.log( $( this ).text() );
});

We moved a from the original selector to the second parameter in the on() method. This second parameter of the on() method tells the handler to listen to this specific event and check whether the triggering element was the second parameter (the a in our case). As the second parameter matches, the handler function is executed. With this delegate event, we are attaching a single handler to the entire ul#list. This handler will listen to the click event triggered by any descendent of the ul element.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset