Understanding Event Delegation Using jQuery

Event Like A Pro

A few years ago eventing in jQuery was re-invented using the concept of delegation. But even today, when I'm out in the field I can see that it hasn't really caught on.

Delegate binding is the very clever descendant of the briefly-popular .live() binding in jQuery.

It leverages the event propagation that naturally occurs in the DOM, giving us increased flexibility and transparency when managing events.

Delegate Binding Using .on() And .off()

We'll use this HTML as our base:


<body>
  <div class="wrapper">    
    <section>      
      <div class="viewport">        
        <div class="content">        
          <button>Trigger Event By Clicking Here</button>          
        </div>        
      </div>      
    </section>    
  </div>  
</body>

And this is an example of delegate binding.


$( "html" ).on('click', 'button',function(e) {
  console.log("the click on <button> has made its way to <html>.");
  var $button = $(e.currentTarget);
  // also: 
  // e.currentTarget == this -> true
});

Think of delegate binding like a net with filter. The <html> is the net catching every event. And when an event matches our filter, a click sent from button, our function is executed.

Here's an illustration:

JavaScript Event Propagation

Note how the click on <button> propagates to <html>, passing through each parent DOM element on its way. This is called event bubbling.

You can also catch this click on lower-level element like <div.wrapper> and prevent it from bubbling to <html&gtl:


$( ".wrapper" ).on('click', "button",function(e) {
	e.stopPropagation();
	console.log("No propagation for you.");
});

Delegate binding allows us to bind once to a high-level element (like <html>) instead of many times to low-elements (like <div>s). This allows us to easily capture events from dynamic ajax content that is added to the DOM after the initial page load.

Drawback To Old School Direct Binding


$( "button" ).click(function(e) {
	console.log( "Handler for .click() called." );
});

This approach binds the event directly to the DOM element. When an ajax requests adds dynamic content to an existing page, you must bind the click to the new elements, while not adding a click a second time to existing elements.

This quickly adds unnecessary complexity.

Anecdotally, I believe this method of direct binding in jQuery has contributed to a gap in understanding how JavaScript events actually propagate inside the browser. So I strongly advocate leaving direct binding in the past.

Closing Thoughts

While this may be rote for some, managing JavaScript events through delegation is a foundational concept to building the modern web app. I hope you enjoyed this and please, don't let your colleagues direct bind.

See the jQuery documentation for more details on binding with .on() and .off().

This article was written using Markdown for Sitecore.

Fish