frenchie
frenchie

Reputation: 51927

replacing jquery.live() with jquery.on() doesn't work

I have several textboxes that are added dynamically after an ajax call. These boxes are tied to event handlers with .live() that currently work fine. I want to replace that with the newer .on() function.

This is what I have

$('.MyTextBox').live({
  mouseenter: function () { .... },
  mouseleave: function () { .... },
  blur: function () { ... }
});

When I replace .live() with .on() it doesn't work; the textboxes don't display their normal behavior after they're added.

If I write $('#MainDiv .MyTextBox').live({... , where MainDiv is the top DOM element where all the action happens, nothing happens either.

What am I missing?

Thanks

Upvotes: 30

Views: 21363

Answers (3)

Aaron Blenkush
Aaron Blenkush

Reputation: 3059

tl;dr: For direct swap-in replacement (accounts for dynamic loading), see the General Example below.


As other posters have noted, the accepted answer works, but $(#MainDiv') needs be a "non-dynamic element (not being loading again through ajax)". This is preferable performance-wise, as the event bubbling "distance" is limited. In the example, it only needs to bubble up to it's parent element to be handled.

The solution would be to bind to the "parent-most" element that is not going to be reloaded (via AJAX usually) - in the example, you'd need to bind to $('#MainDiv')'s parent.

However,

If you do want a direct swap-in replacement for live(), all you need to do is bind to the document element instead.

Generic examples

format 1:

//Replace:
$(selector).live(events, handler);           // Where `events` is a string

//With:
$(document)  .on(events, selector, handler); 

format 2:

//Replace:
$(selector).live(events);                    // Where `events` is 
                                             //   an object of `handler`s
//With:                                      //   (as in OP's example)
$(document)  .on(events, selector);

Note that with the on() examples,selector's container(s) can change and the binding will be automatically applied; the same functionality as live().

OP's example (format 2)

//Deprecated live() version:
$('.MyTextBox').live({
   mouseenter: function () { .... },
   mouseleave: function () { .... },
   blur: function () { ... }
});

//New on() version
$(document).on({
   mouseenter: function () { .... },
   mouseleave: function () { .... },
   blur: function () { ... }
},'.MyTextBox');

Upvotes: 18

Joe H
Joe H

Reputation: 827

Aaron, Matt, I think you've got the selector in the wrong order (for a live conversion), Have a look at the API documentation for on- http://api.jquery.com/on/#example-7

$("body").on("click", "p", function(){
  //stuff
});

When I tried your method (I came here looking for a solution for updating my core version), console errors popped up for everything (1.8, 1.9 and 2.0). The target element should be the second parameter not the last. Not sure why your answer has been accepted as it doesn't work. Hope this helps.

Upvotes: 1

Matt
Matt

Reputation: 7249

Heres the example they have, but with the delegate:

http://jsfiddle.net/HDtz3/

vs non-delegate: http://jsfiddle.net/HDtz3/1/

This is why i hate the new on syntax.

In yours simply do:

$('#MainDiv').on({
  mouseenter: function () { .... },
  mouseleave: function () { .... },
  blur: function () { ... }
}, '.MyTextBox');

and it should work

Upvotes: 35

Related Questions