211

My application has dynamically added Dropdowns. The user can add as many as they need to.

I was traditionally using jQuery's live() method to detect when one of these Dropdowns was change()ed:

$('select[name^="income_type_"]').live('change', function() {
    alert($(this).val());
});

As of jQuery 1.7, I've updated this to:

$('select[name^="income_type_"]').on('change', function() {
    alert($(this).val());
});

Looking at the Docs, that should be perfectly valid (right?) - but the event handler never fires. Of course, I've confirmed jQuery 1.7 is loaded and running, etc. There are no errors in the error log.

What am I doing wrong? Thanks!

0lukasz0
  • 3,155
  • 1
  • 24
  • 40
Jack
  • 9,615
  • 18
  • 72
  • 112
  • 2
    I know this is late but it seems that jQuery `live` is actually using `on` anyway, so a re-write of legacy code might not be needed just yet until `live` will be removed, which I believe is 1.9. Excerpt from 1.7.1 source: `live: function( types, data, fn ) {jQuery( this.context ).on( types, this.selector, data, fn ); return this;}` So if one is not upgrading to a version in which `live` is gone an update may not be needed right away for legacy code. For **new** code off course using `on()` instead is as recommended. I just thought this information might help someone else at some stage. – Nope Dec 22 '12 at 04:46
  • 1
    See [Migration Examples](http://stackoverflow.com/a/14354091/584192) on how to change `live` to `on`. – Samuel Liew Jul 22 '13 at 10:08

5 Answers5

252

The on documentation states (in bold ;)):

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().

Equivalent to .live() would be something like

$(document.body).on('change', 'select[name^="income_type_"]', function() {
    alert($(this).val());
});

Although it is better if you bind the event handler as close as possible to the elements, that is, to an element being closer in the hierarchy.

Update: While answering another question, I found out that this is also mentioned in the .live documentation:

Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Feel a bit silly now, did read them but was in panicky-programmer-mode and only searched for the important bits ;) Thanks! – Jack Nov 05 '11 at 16:21
  • 5
    @Jack: No worries, IMO it's a good question. I assume others will stumble over this as well when they try to convert all the `bind`, `live` and `delegate` calls to `on`. – Felix Kling Nov 05 '11 at 16:30
  • 4
    Ah yes, and of course we only see this answer after running a blanket find and replace from `.live` > `.on` – ajbeaven Nov 07 '11 at 23:06
  • 3
    IMO, the ``.on`` syntax is more logical, since the listener is actually attached to the selector that you provide. When the event is triggered, jQuery traverses the DOM and executes handlers where specified (simple event delegation). ``.live`` suggested that there was something "magical" that happened, and it was said to attach event handlers for "future elements" which wasn’t entirely true. – David Hellsing Dec 12 '11 at 17:15
  • 1
    @FelixKling that is correct - I stumbled across this also! Thanks – willdanceforfun Apr 05 '12 at 03:41
  • @FelixKling, may I request you to have a look at a jquery question on a different topic here : http://stackoverflow.com/questions/13137404/jquery-find-div-class-name-at-a-certain-position-while-scrolling ? – Istiaque Ahmed Oct 31 '12 at 09:07
  • 2
    For the search engine: The jQuery ".live()" method is depreciated since v1.7 and removed in v1.9. Fix your scripts by using the ".on()" method instead. Surprisingly this also affects the current Microsoft jquery.unobtrusive-ajax.js v2.0.20710.0 (Microsoft didn't update their scripts either so now it is broken). – Tony Wall Jan 30 '13 at 13:05
  • @david one MIGHT say using plain JavaScript is 'more logical', as it is directly attached to exactly what it's attached to, and does exactly what it does when it's supposed to do it. It doesn't mess around with any unnecessary "libraries" or "frameworks" that provide unused functionality (If I don't need AJAX on a page, why dedicate almost a kilobyte to a library that makes it easier to do? __I'm not doing it__)... IMO, _everything_ in jQuery is to one extent or another, "magical" - the question is: "What is the price of that magic, and how useful or confusing is it or its alternatives?" – Code Jockey Jun 11 '15 at 14:09
  • Isn't this last suggest horribly inefficient? By attaching to `$(document)`, the handlers are being checked at the document level. – Jonathan Wood Jun 28 '16 at 17:16
  • @JonathanWood: `.live` did that too. – Felix Kling Jun 28 '16 at 18:23
  • @JonathanWood: The difference is that `.live` did that implicitly so people didn't really know what it really did, which is also one of the reasons it was deprecated. – Felix Kling Jun 28 '16 at 18:30
26

In addition to the selected answer,

Port jQuery.live to jQuery 1.9+ while you wait for your application to migrate. Add this to your JavaScript file.

// Borrowed from jQuery 1.8.3's source code
jQuery.fn.extend({
  live: function( types, data, fn ) {
          if( window.console && console.warn ) {
           console.warn( "jQuery.live is deprecated. Use jQuery.on instead." );
          }

          jQuery( this.context ).on( types, this.selector, data, fn );
          return this;
        }
});

Note: Above function will not work from jQuery v3 as this.selector is removed.

Or, you can use https://github.com/jquery/jquery-migrate

TheMohanAhuja
  • 1,855
  • 2
  • 19
  • 30
Vikrant Chaudhary
  • 11,089
  • 10
  • 53
  • 68
6

Just found a better solution which doesn't involve editing third party code:

https://github.com/jquery/jquery-migrate/#readme

Install the jQuery Migrate NuGet package in Visual Studio to make all the versioning issues go away. Next time Microsoft update their unobtrusive AJAX and validation modules perhaps try it without the migrate script again to see if they resolved the issue.

As jQuery Migrate is maintained by the jQuery Foundation I think this is not only the best approach for third party libraries and also to get warning messages for your own libraries detailing how to update them.

Tony Wall
  • 1,382
  • 20
  • 18
4

In addition to the selected answers,

If you use Visual Studio, you can use the Regex Replace.
In Edit > Find and Replace > Replace in Files
Or Ctrl + Shift + H

In Find and Replace pop-up, set these fields

Find what: \$\((.*)\)\.live\((.*),
Replace with: $(document.body).on($2,$1,
In find options check "Use Regular Expressions"

Maykol Rypka
  • 531
  • 6
  • 19
-1

jquery verision x.x.x.js open editor, find jQuery.fn.extend

add code

live: function( types, data, fn ) {
        jQuery( this.context ).on( types, this.selector, data, fn );
        return this;
    },

Example : jquery-2.1.1.js --> line 7469 (jQuery.fn.extend)

Example images view