jQuery Event Handlers – From Live to On

Today, we are going to look at jQuery’s (almost) recent change from using the .live() function to using .on() for handling events.

Any frontend jQuery developer will have come across issues of using event handlers like .click(), .blur() and .focus() on HTML elements created after the Document Object Model (or, the DOM) has loaded. Up until version 1.7, jQuery provided us with the nice function .live() to attach element handlers to these newly created HTML objects. Post 1.7 though this function was deprecated, for reasons I’ll explain in a moment.

For those with their fingers on the jQuery pulse, this was spotted back at the end of 2011. However, not everyone reads the change notes of each jQuery version so deprecated functions often go unnoticed until they’re removed completely, as with .live() in version 1.9.

So, why the change?

Firstly, while .live() has been a revelation for us all over the last few years, its not actually that efficient in how it works. The basic reason behind this is that when you use .live(), the listener for that event is attached to the top level document by default, meaning that an event has to bubble up the DOM tree (working its way through every parent element) until it finds handlers to deal with it. While this is fine for smaller documents, the bigger your page and your DOM tree, the longer this will take.

Secondly, functions like event.stopPropagation() are rendered useless, as the event has already propagated to the very top of the DOM by the time any handler is called, so you just end up trying to close the gate well after the horse has bolted.

.on() in comparison

The ‘new’ .on() function allows you to specify which parent element we’re attaching an event to, removing the need for the event to bubble through the DOM tree searching for a handler, and allowing it to trigger much more quickly. This parent element can still be the document if you wish, however we can also get a lot more specific if we need to.

Side by side examples

Some simple HTML for us to use in our examples;

<div id="box">
<a href="#" class="link">Click Here</a>

So, a function we’re all probably familiar with is the one below;

$('.link').live('click', function() { /* do something here */ });

Creating the exact same event behaviour (by attaching the event to the document) using .on() would be;

$(document).on('click', '.link', function() { /* do something here */ });

And as I mentioned, we can also get much more specific with where we attach our event handler;

$('#box').on('click', '.link', function() { /* do something here */ });

So you can see now we pass two elements into the function, the first that we’re attaching the event handler to goes within the selector;

$('#just here')

..and then the second is the object that will trigger the event, as the second parameter passed into the .on() function;

.on(event, '.just here', function)

Is it actually better?

Yes would be the short answer. Forcing the user to select an object to attach the handler to will mean less events bubbling through the DOM tree, and less handlers attached to the document. These both have a positive impact on performance, with some tests showing that .on() can run two or three times the amount of operations per second than .live() can.

JQuery’s change to this function is certainly for the best, despite us all having to recode our events when we upgrade jQuery! If you’ve any questions or comments, please let me know below.