Recently, a fellow developer at Bootstrap gave a couple of talks about JavaScript and jQuery. In particular, he discussed how jQuery’s live() and delegate() methods can improve performance and reduce repetition in your code.
Normally, when using jQuery to add functionality to an element (for example, binding a delegate function to the click event of an anchor element), we’d have to write something like:
function initializeAnchors() {
$("a").click(function() {
functionToCall();
});
}
However, in this example, every time a user clicks on any link on the page, all of the anchor elements on that page get processed. One way to optimize this is to call this function for an explicitly-passed anchor:
function initializeAnchor(anchor) {
$(anchor).click(function() {
functionToCall();
});
}
The downside of this approach is that whenever we add a new anchor element, we would have to specifically call this function to bind that anchor’s click event to the delegate.
As a result, we would have to call initializeAnchor(thisAnchor); and initializeAnchor(thatAnchor); over and over in our code, leading to bulky code that is difficult to maintain and error-prone.
As of version 1.4, jQuery introduced the live() and delegate() functionality.
This means that you no longer need to bind a delegate to an event after creating an element.
Instead, every time an element is created that would have been selected by jQuery, the specified event is automatically bound.
Let’s try it:
$("a").live("click", functionToCall());
Now, all anchor elements that are ever created will call functionToCall() when they’re clicked. We’ve solved the problem of having repetitive code, but we haven’t solved the performance problem.
The issue is that the selection process that jQuery runs is a very expensive operation, because it must parse the entire DOM before returning its wrapped result set. The live() method runs this selection process every time it gets called (which, in this case, is every time a new anchor element is added to the DOM.)
This is where delegate() comes in. If, for example, we know all of our anchor elements will reside within a div element with a class of dynamicAnchorsDiv, then we can use delegate() to improve the performance of our JavaScript substantially. That’s because delegate() lets you bind a target function to the events of specific DOM elements, rather than the entire tree.
This gives us:
$("div.dynamicAnchorsDiv").delegate("a", "click", functionToCall());
This code will execute functionToCall() whenever an anchor element in our div is clicked, without requiring us to bind that event ourselves and without jQuery running through the entire DOM each time. The final bonus of using deletegate() is that it’s methods are chainable, one of the greatest benefits of jQuery in general.
What does that mean? It means that we have to write less code, which lowers the risk of introducing bugs, makes updates and enhancements easier to write, and brings lots of happiness to developers like us.
