Why use jQuery on() instead of click()

Currently with jQuery when I need to do something when a Click occurs I will do it like this...

$(".close-box").click( function() {
    MoneyBox.closeBox();
    return false;
});

I was looking at some code someone else has on a project and they do it like this...

$(".close-box").live("click", function () {
    MoneyBox.closeBox();
    return false;
});

Notice it seems to do the same thing as far as I can tell except they are using the live() function which is now Deprecated and jQuery docs say to use on() instead but either way why use live/on() instead of my first example?


Solution 1:

Because you might have a dynamically generated elements (for example coming from an AJAX call), you might want to have the same click handler that was previously bound to the same element selector, you then "delegate" the click event using on() with selector argument

To demonstrate:

http://jsfiddle.net/AJRw3/

on() can also be synonymous with click() if you don't have a selector specified:

$('.elementClass').click(function() { // code 
});

is synonymous with

$('.elementClass').on('click', function() { // code
});

In the sense that it only add the handler one time to all elements with class elementClass. If you have a new elementClass coming from, for example $('<div class="elementClass" />'), the handler won't be bound on that new element, you need to do:

$('#container').on('click', '.elementClass', function() { // code
});

Assuming #container is .elementClass's ancestor

Solution 2:

There are a lot of answers, each touching on a few points - hopefully this can give you your answer, with a good explanation of what's what and how to use it.

Using click() is an alias to bind('click' ...). Using bind() takes the DOM as it is when the event listener is being set up and binds the function to each of the matching elements in the DOM. That is to say if you use $('a').click(...) you will bind the function supplied to the click event of every anchor tag in the DOM found when that code runs.

Using live() was the old way in jQuery; it was used to bind events just like bind() does, but it doesn't just bind them to elements in the DOM when the code runs - it also listens to changes in the DOM and will bind events to any future-matched elements as well. This is useful if you're doing DOM manipulation and you need an event to exist on some elements that may get removed/updated/added to the DOM later but don't exist when the DOM is first loaded.

The reason that live() is now depreciated is because it was poorly implemented. In order to use live(), you had to be able to select at least one element in the DOM initially (I believe). It also caused a copy of the function to run to be bound to each element - and if you have 1000 elements, that's a lot of copied functions.

The creation of the on() function was to overcome those problems. It lets you bind a single event listener to an object that will not change in the DOM (so you can't use on() on an element that will be removed/added to the DOM later - bind it to a parent object), and simply apply an element "filter" so that the function is only run when it is bubbled up to an element that matches the selector. This means you have just one function that exists (not a bunch of copies) bound to a single element - a much better approach to adding "live" events in the DOM.

... and that is what the differences are, and why each function exists and why live() is depreciated.

Solution 3:

  • $("a").live() --> It will apply to all <a>, even if it is created after this is called.
  • $("a").click() --> It will only apply to all <a> before this is called. (This is a shortcut of bind(), and on() in 1.7)
  • $("a").on() --> Provides all functionality required for attaching event handlers. (Newest in jQuery 1.7)

Quotes:

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
This method provides a means to attach delegated event handlers to the document element of a page, which simplifies the use of event handlers when content is dynamically added to a page. See the discussion of direct versus delegated events in the .on() method for more information.

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers.

For earlier versions, the .bind() method is used for attaching an event handler directly to elements.

Solution 4:

click() is a shortcut to the non delegation method of on(). So:

$(".close-box").click() === $(".close-box").on('click')

To delegate events with on(), ie. in dynamic created objects you can do:

$(document).on('click', '.close-box') // Same as $('.close-box').live()

But, on() introduces delegation in any static element, not just document as live() does, so:

$("#closestStaticElement").on('click', '.close-box')

Solution 5:

You should read up on the difference between live and bind.

In a nutshell, live uses event delegation, allowing you to bind to elements that exist now and in the future.

In contrast, handlers attached via bind (and its shortcuts, like click) attach handlers directly to the DOM elements matching the selector, and therefore are only bound to elements that exist now.

A consequence of live's flexibility is decreased performance, so only use it when you need the functionality it provides.