0

Possible Duplicate:
jQuery 1.7 - Turning live() into on()

Just switching my code from "live" to "on" and some events just don't fire any more, here is an example, can anyone please help out saying what's wrong with it? It WORKED 100% correct with "live" instead of on method before....

$('a#doBulkLink').on('click', function (e) {

    createLabelsWithDestinationFolders();

    $('label.moveDocDestinationFolder').on('click', function (e) {

        doSomeAjaxStuffWithLabels();
        e.stopImmediatePropagation();  

    });

    e.preventDefault();
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
alchemication
  • 5,084
  • 6
  • 22
  • 21
  • why are you switching? what jquery version are you using? – Th0rndike Mar 27 '12 at 15:29
  • 2
    Posting the working code that uses `.live()` would have been a good idea so that we can compare the two. – Anthony Grist Mar 27 '12 at 15:30
  • +1 to Anthony. This question needs to be closed. Next, `live()` has LONG been considered a really poor function to use. `$(document).on()` suggested in the answers below is the 'correct' answer since it is equivalent to `live()` but nobody is taking the time to tell you that it's a bad idea the same way `.live()` was a bad idea. :-/ – Greg Pettit Mar 27 '12 at 15:33
  • @GregPettit: `$(document).on()` is *not* a bad idea. `live()` was a bad idea because it hid the underlying implementation too much from the user. – Matt Mar 27 '12 at 15:41
  • @Matt No, the major problem with `live()` was the inefficiency of the listener, not the syntax. When possible, you should listen to the nearest ancestor that will get the job done. That's why the recommendation was to use `delegate()` and a reasonable listener. – Greg Pettit Mar 27 '12 at 16:10
  • * "listen with the nearest ancestor" – Greg Pettit Mar 27 '12 at 17:09

4 Answers4

5

You cannot replace live() with on() simply by changing the function name to on(); the signature changes as well.

$('selector').live('event', function () {

});

... becomes ....

$(document).on('event', 'selector', function () {

});

In it's current form, what you have is a direct replacement for bind() (of which click(), change() etc are aliases). As such, the handler is been bound directly to the element, rather than binding the handler to the document and taking advantage of event bubbling, which is what live() did.

Matt
  • 74,352
  • 26
  • 153
  • 180
  • Hi All, I actully played quite a bit with the documentation (thx JQuery, it's really good), ok, maybe should have written a bit more.. Tried $(document) and tried syntax with 'selector' as parameter for the "on" method and still no sign of firing the second event. My old code was exactly te same as with "on" but using "live". Using JQuery 1.7.1 and noticed that "live" is becoming depricated. Thanks All. Adam. – alchemication Mar 27 '12 at 15:57
  • This is a line copied from JQuery Documentation: $("button").on("click", notify); What can you say about that Matt? – alchemication Mar 27 '12 at 21:19
  • @alchemication: `on()` replaces `live()`, `bind()` **and** `delegate()`. In that circumstance, the documentation is talking about the usage of `on`()` which replaces `live()`. Search for "Rewriting the .live() method" in the [`live()` documentation](http://api.jquery.com/live) – Matt Mar 28 '12 at 09:01
  • 1
    True, it took me a while to figure out that I can actually use "on" everywhere, but with slightly different syntax, you are right, thanks. – alchemication Mar 29 '12 at 07:57
1

To use on() in the same manner as live(), do it as such:

$(document).on('click', 'a#doBulkLink', function() { } );

As indicated in the docs here: http://api.jquery.com/live/

jeremyharris
  • 7,884
  • 22
  • 31
  • Did that, didn't work, but thanks for reply. Actually I spent 4 hours today with documentation and Google :/ bleee. – alchemication Mar 27 '12 at 16:00
  • I used `$('document')` actually instead of `$(document)`...my bad...I will check it out tomorrow and let you know, thx – alchemication Mar 27 '12 at 21:27
  • YES, it's working thank you very much, I'm just so used to use the quotes in the JQuery syntax that I've put document as `$('document)`. FIXED!! – alchemication Mar 28 '12 at 07:38
0

The way you have defined .on will not work if a#doBulkLink is inserted dynamically to the dom,

Try,

//replace document with any closest container of 'a#doBulkLink' which is available 
//in dom when this code is executed.

$(document).on ('click', 'a#doBulkLink', function () {
    createLabelsWithDestinationFolders();

    $('label.moveDocDestinationFolder').on('click', function (e) {

        doSomeAjaxStuffWithLabels();
        e.stopImmediatePropagation();  

    });

    e.preventDefault();

});
Selvakumar Arumugam
  • 79,297
  • 15
  • 120
  • 134
  • Hi, a#bulkLink is not dynamically inserted at all, but label.moveDocDestinationFolder labels are, tried your code, this one does not even fire the first event click. Thank for help anyway. – alchemication Mar 27 '12 at 16:04
  • @alchemication If the labels are added dynamically, then it has to follow the similar syntax. `$(document).on ('click', 'label.moveDocDestinationFolder', function () { ... })` – Selvakumar Arumugam Mar 27 '12 at 17:19
  • Thanks, Actually I made a lot of mistakes today...what a day... first of all first event can be treated with "click", cause a#bulkList exists on the page and I am only un-hiding it, and second I used $('document') instead of $(document) !!!!! My BAD, will check it tomorrow and let you know... THANKS!!! – alchemication Mar 27 '12 at 21:22
  • YES, it's working thank you very much, I'm just so used to use the quotes in the JQuery selector syntax that I've put document as `$('document)`. FIXED!! (I am a goat) ... ;) – alchemication Mar 28 '12 at 07:39
0

I got it working, FIXED!!!!, I made 2 silly mistakes:

  • First event (on a#doBulkLink) is not dynamic (It was on the hidden element that exists on a page, and that#s what tricked me!)
  • In second event (on label.moveDocDestinationFolder) I used $('document') instead of $(document) in my JQuery ".on" method syntax,

So the code looks like this and it's working WELL in 100%:

// this is not dynamically added element, but still can use ".on" to attach an event to 
// outer div and delegate to a#doBulkLink when clicked
$('div#doBulkLinkBox').on('click', 'a#doBulkLink' ,function (e) {

    createLabelsWithDestinationFolders();

    // these are dynamic elements so let's use "on" to attach a click event
    $(document).on('click', 'label.moveDocDestinationFolder', function (e) { 
        doSomeAjaxFunkWithLabels();
        e.stopImmediatePropagation();  
    });

    e.preventDefault();
});

THANKS to everyone for tips!!

alchemication
  • 5,084
  • 6
  • 22
  • 21
  • Maybe I'm incorrect about this, but I believe you can stop the use of the stopPropagation() and preventDefault (unless you're preventing something else from defaulting), since using on() defines how far it bubbles (from the first part $('div#doBulkLinkBox)) and those events just stop it as well. – Dylan Cross Mar 28 '12 at 08:42
  • @Dylan Cross, `e.preventDefault()` holds anchor tag from forwarding so it's a must... When I remove `e.stopPropagation()` the `doSomeAjaxFunkWithLabels();` function gets called 1+ times every time user clicks on 'label.moveDocDestinationFolder', so it's a must as well. – alchemication Mar 29 '12 at 08:03