Event Delegation with jQuery

Share this article

jQuery makes event handling in JavaScript easy. However, the more event handlers you define, the more memory you use, which can end up decreasing performance and making the UI sluggish. This article looks at how event delegation can help prevent this, and how you can apply event delegation with jQuery. Event delegation is an event handling technique where, instead of attaching event handlers directly to every element you want to listen to events on, you attach a single event handler to a parent element of those elements to listen for events occurring on it’s descendant elements. When handling the event, you check which element fired the event, and respond accordingly. Event delegation relies on event bubbling in the DOM. This is the process whereby an event triggered on a child element propagates up the DOM tree to its parent element, and its parent’s parent element, etc., until the document is reached. Bubbling can also be stopped by the programmer using event.stopPropagation(). Note that not all DOM events propagate – focus, blur, load, and unload don’t. Event delegation uses less memory because you replace multiple event handlers with a single event handler. For example, if you attach event handlers to each link in a list of ten links, you’d have ten event handlers taking up space in memory. If, instead, you use event delegation and handle events at the parent <ul> element, you only create one event handler and use less memory than you would’ve attaching to each link individually. In addition to reduced memory consumption, event delegation also has the following benefits.

  • No need to manually manage events when elements are added or removed from the DOM. If we used traditional event handling, we’d have to attach event handlers to elements added to the DOM, and remove event handlers from elements removed from the DOM.
  • Less code to manage, through fewer event handling functions. This can leave us with simpler code, without any duplicated event handling logic, which can help keep our JavaScript nice and DRY.

An Example of Event Delegation in jQuery

Suppose you’re developing a single page application that sells pictures of kittens. When the page loads, the first 20 kittens are displayed. As the user scrolls down the page, more kittens are loaded. Our HTML is shown below.
<section id="cats">
  <ul>
    <li>
      <img src="http://placekitten.com/200/200" alt=""/>
      <a href="/moreinfo">More info</a>
      <button>Add to cart</button>
    </li>
    ...
  </ul>
</section>
With traditional event handling, we’ll need to wire up event handlers to:
  1. Display a larger picture when the user clicks on a thumbnail.
  2. Display more info when the user clicks on the ‘More info’ link.
  3. Add the picture to the shopping cart when the user clicks ‘Add to cart’.
  4. Attach these three events to the new DOM elements that are added as the user scrolls down the page.
This code will resemble the following example. Note that this is boilerplate code intended to show how attaching event handlers to individual elements differs from using event delegation, so no implementation is given for the loadImage(), moreInfo(), addToCart(), and loadNewKittens()
functions.
$(document).ready(function() {
  var cats = $('#cats');

  cats.find('img')
    .on('click', function() {
      loadImage();
    })

  cats.find('a')
    .on('click', function(event) {
      event.preventDefault();
      moreInfo();
    });

  cats.find('button')
    .on('click', function() {
      addToCart();
    });

  $(window).scroll(function() {
    var fragment = loadNewKittens();
    // attach event handlers for new DOM elements
    fragment.find('img')
      .on('click', function() {
        loadImage();
      });

    fragment.find('a')
      .on('click', function(event) {
        event.preventDefault();
        moreInfo();
      });

    fragment.find('button')
      .on('click', function() {
        addToCart();
      });

    fragment.appendTo('#cats ul');
  });
});
That’s quite a bit of code. Now let’s see how our code looks if instead we use event delegation:
$(document).ready(function() {
  $('#cats')
    .on('click', 'img, a, button', function(event) {
      event.preventDefault();
      var target = event.target;

  switch(target.tagName.toLowerCase()) {
    case 'img':
      loadImage();
      break;
    case 'a':
      moreInfo();
      break;
    case 'button':
      addToCart();
      break;
    default:
      // do nothing
  }
});

  $(window).scroll(function() {
    var fragment = loadNewKittens();
    fragment.appendTo('#cats ul');
  });
});
The key is the optional second argument to on(). By passing a selector here, on() knows it’s dealing with a delegated event handler rather than a directly bound event handler. Our event handling code is a lot simpler now too. By getting a hold of event.target, and switching on it’s tagName, we can tell which element fired the event and can respond appropriately. Plus, we no longer have to attach event handlers for elements loaded in $(window).scroll, as the events fired by these new elements are delegated to the parent element. A potential ‘gotcha’ to be aware of when using event delegation is that any event handlers attached to child elements are handled before
the deletated event handler fires. Therefore, it’s possible for a child event handler to call event.stopPropagation() or return false, which will prevent the event from bubbling up to the delegated event handler, and leave you scratching your head as to why your event isn’t being delegated.

Conclusion

In this article we’ve looked at event delegation. We’ve seen how it can help improve the performance of your site by lessening the event handling load it has to bear. We’ve also seen how to implement event delegation in jQuery via the on() function.

Frequently Asked Questions about Event Delegation with jQuery

What is event delegation in jQuery and why is it important?

Event delegation in jQuery is a technique that allows you to attach a single event listener to a parent element that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future. This is important because it can greatly improve performance by reducing the number of event handlers needed for an application. Instead of attaching individual event handlers to each element, you can delegate the event to a parent element. This is particularly useful in dynamic applications where elements are added or removed.

How does event delegation work in jQuery?

Event delegation works in jQuery by taking advantage of the fact that most events in jQuery bubble, or propagate, up the DOM tree. When an event is triggered on a child element, it will bubble up to its parent elements. By attaching an event listener to a parent element, you can catch events triggered on any of its child elements. The event.target property can be used to determine which child element triggered the event.

What is the difference between direct and delegated events in jQuery?

Direct events are attached directly to specific elements and only those elements can trigger the event. On the other hand, delegated events are attached to a parent element and any child element can trigger the event. Delegated events have the advantage of being able to handle events from child elements that are added dynamically.

How do I use the .on() method for event delegation in jQuery?

The .on() method in jQuery is used for attaching event handlers. For event delegation, you would use it with three arguments: the event type, a selector string to filter the descendants, and a handler function. The event type is a string representing the type of event (e.g., ‘click’), the selector string is used to filter the descendants of the selected elements that trigger the event, and the handler function is the function to execute when the event is triggered.

Can I use event delegation with dynamically added elements in jQuery?

Yes, one of the main advantages of event delegation in jQuery is that it can handle events from elements that are added dynamically. Since the event listener is attached to a parent element, it can catch events triggered on any of its child elements, even those that are added after the event listener is attached.

What is event bubbling and how does it relate to event delegation in jQuery?

Event bubbling is a type of event propagation where the event starts from the specific element that triggered it and then bubbles up to its ancestors. Event delegation in jQuery takes advantage of event bubbling by attaching the event listener to a parent element. When an event is triggered on a child element, it will bubble up to the parent element where the event listener can catch it.

How can I stop event propagation in jQuery?

You can stop event propagation in jQuery using the .stopPropagation() method. This method prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event. However, it should be used sparingly as it can make your code harder to debug and understand.

What is the difference between .bind() and .on() methods in jQuery for event handling?

The .bind() method in jQuery is used to attach an event handler directly to elements. The .on() method, on the other hand, can be used to attach an event handler directly to elements (like .bind()) or to a parent element for event delegation. The .on() method is more versatile and is the preferred method for attaching event handlers in jQuery.

Can I use event delegation with custom events in jQuery?

Yes, you can use event delegation with custom events in jQuery. Just like with standard events, you can attach an event listener to a parent element that will catch custom events triggered on any of its child elements.

How can I remove an event handler in jQuery?

You can remove an event handler in jQuery using the .off() method. This method can be used to remove all event handlers on an element, or only event handlers attached with a specific event type or namespace.

Ian OxleyIan Oxley
View Author

Ian Oxley has been building stuff on the Web professionally since 2004. He lives and works in Newcastle-upon-Tyne, England, and often attends local user groups and meetups. He's been known to speak at them on occasion too. When he's not in front of a computer Ian can be found playing guitar, and taking photos. But not usually at the same time.

eventsIntermediatejQuery
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week