26

I usually use

$(selector).click(...

But some people recommend me to use this instead:

$(selector).on("click", function(...

Or $(selector).live("click"... (Deprecated)

I read the manual, but my begginer's mind couldn't understand it. I got confused with all the terminology they used. I still do not know the difference nor why to use .on()
http://api.jquery.com/on/

1
  • 1
    From the docs: "As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For equivalents to older jQuery event methods, see .bind(), .delegate(), and .live()." Commented Nov 5, 2011 at 10:39

3 Answers 3

34

At the end of the day, every event is bound to some element in the DOM. In the case of .bind, you're binding directly to the element (or elements) in your jQuery object. If, for example, your jQuery object contained 100 elements, you'd be binding 100 event listeners.

In the case of .live, .delegate, and .on, a single event listener is bound, generally on one of the topmost nodes in the DOM tree: document, document.documentElement (the <html> element), or document.body. Because DOM events bubble up through the tree, an event handler attached to the body element can actually receive click events originating from any element on the page. So, rather than binding 100 events you could bind just one.

For a small number of elements (fewer than five, say), binding the event handlers directly is likely to be faster (although performance is unlikely to be an issue). For a larger number of elements, always use .on.

The other advantage of .on is that if you add elements to the DOM you don't need to worry about binding event handlers to these new elements. Take, for example, an HTML list:

<ul id="todo">
  <li>buy milk</li>
  <li>arrange haircut</li>
  <li>pay credit card bill</li>
</ul>

Next, some jQuery:

// Remove the todo item when clicked.
$('#todo').children().click(function () {
  $(this).remove()
})

Now, what if we add a todo?

$('#todo').append('<li>answer all the questions on SO</li>')

Clicking this todo item will not remove it from the list, since it doesn't have any event handlers bound. If instead we'd used .on, the new item would work without any extra effort on our part. Here's how the .on version would look:

$('#todo').on('click', 'li', function (event) {
  $(event.target).remove()
})
5
  • why did you use $(event.target).remove(); instead of $(this).remove();? Also, I tried it in JSFiddle and could not make it work :-( http://jsfiddle.net/u6qWs/1/
    – Omar
    Commented Nov 5, 2011 at 8:06
  • @Omar Good point about event.target. At the time I wrote this I was not sure of the binding of this within event handlers passed to .on. Having just read the method's documentation I now realize that this and event.type will refer to the same object in this case (but don't in all cases). Commented Nov 5, 2011 at 9:39
  • @Omar The .on method was added in jQuery 1.7 which has just been released. Your fiddle uses jQuery 1.6.4. Commented Nov 5, 2011 at 9:42
  • @davidchambers oops! I fixed the fiddle. Thanks for pointing it out. IT'S ALIVE!!! http://jsfiddle.net/u6qWs/4/ By the way, your sample is great, but it's missing a semicolon ";" at the end of every line.
    – Omar
    Commented Nov 5, 2011 at 16:08
  • A little observation using the click() method on children "$('#todo').children()" with the above mentioned function will remove the children object itself.Hence no children object= no object for an event. On the other hand using the .on method on #todo will not remove the #todo object but target all 'li elements'..I think this is the point that should be brought out..the .on click method can take elements as arguments
    – repzero
    Commented Jun 5, 2015 at 4:06
12

In the plain .click(... if the target of the selector changes on the fly (e.g via some ajax response) then you'd need to assign the behavior again.

On .live(... the behavior will be automatically be reapplied on the selector.

The .on(... is very new (jQuery 1.7) and it can cover the live scenario using delegated events which is a faster way to attach behavior anyway.

6
  • So...If I clone an element, or dynamically create content with ajax, If I use .click() wont work on the new content, but .on("click") it will work? I think it's called binding methods/events?
    – Omar
    Commented Nov 5, 2011 at 7:24
  • Also .on() can be used to attach multiple events simultaneously using a map. Commented Nov 5, 2011 at 7:25
  • 1
    @Omar: Yes, assuming you have got the delegation correctly. E.g if you are talking about trs inside a table then you need to do $("#myTable").on("click", "tr", .... Have a look at api.jquery.com/on
    – cherouvim
    Commented Nov 5, 2011 at 7:27
  • @pedram-behroozi I do not even know what a jQuery map is...it uses a GPS? :p. Aaaaa...how do you attach multible events simultaneously using a map?
    – Omar
    Commented Nov 5, 2011 at 7:27
  • @cherouvim I read api.jquery.com/on ...but like I explained, I am a beginner and do not understand all the terminology they used. I got more confused :-(
    – Omar
    Commented Nov 5, 2011 at 7:30
8

The only difference is that .click() will be applied on the elements that exist in the DOM with that particular selector (only the ones that already exist ).
In the other hand .on(selector ,"click",callback); will be applied on all the elements that match that selector even in the future, let me give an example :

$('p').click(function(){
$(this).next('<p>this is a copy of the previous paragraph </p>');
});

If you click on the paragraph that says "this is a copy of the previous paragraph" (the new one ) you don't get the result that you want which is to add a paragraph next to the clicked one because it was not there at the beginning

but if you use

$('p').on("click",function(){
$(this).next('<p>this is a copy of the previous paragraph </p>');
});

you will get what you want (because .on or .delegate find the match even with the new ones)

Not the answer you're looking for? Browse other questions tagged or ask your own question.