Convertir live () en on () en jQuery

202

Mi aplicación ha agregado dinámicamente menús desplegables. El usuario puede agregar tantos como sea necesario.

Tradicionalmente estaba usando el live()método de jQuery para detectar cuándo se editó uno de estos menús desplegables change():

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

A partir de jQuery 1.7, he actualizado esto a:

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

Mirando los documentos, eso debería ser perfectamente válido (¿verdad?), Pero el controlador de eventos nunca se activa. Por supuesto, he confirmado que jQuery 1.7 está cargado y ejecutándose, etc. No hay errores en el registro de errores.

¿Qué estoy haciendo mal? ¡Gracias!

Jack
fuente
2
Sé que es tarde, pero parece que jQuery en liverealidad lo está utilizando de ontodos modos, por lo que es posible que aún no se necesite volver a escribir el código heredado hasta liveque se elimine, lo que creo que es 1.9. Extracto de la fuente 1.7.1: por lo live: function( types, data, fn ) {jQuery( this.context ).on( types, this.selector, data, fn ); return this;}tanto, si uno no está actualizando a una versión que ya no liveexiste, es posible que no se necesite una actualización inmediata para el código heredado. Para el nuevo código, por supuesto, el uso en su on()lugar es el recomendado. Solo pensé que esta información podría ayudar a alguien más en algún momento.
No
1
Ver ejemplos de migración sobre cómo cambiar livea on.
Samuel Liew

Respuestas:

246

La ondocumentación indica (en negrita;)):

Los controladores de eventos están vinculados solo a los elementos seleccionados actualmente; deben existir en la página en el momento en que su código realiza la llamada .on().

Equivalente a .live()sería algo así como

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

Aunque es mejor si vincula el controlador de eventos lo más cerca posible de los elementos, es decir, de que un elemento esté más cerca en la jerarquía.

Actualización: al responder otra pregunta, descubrí que esto también se menciona en la .livedocumentación :

Reescribir el .live()método en términos de sus sucesores es sencillo; Estas son plantillas para llamadas equivalentes para los tres métodos de conexión de eventos:

$(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
fuente
55
@ Jack: No te preocupes, IMO es una buena pregunta. Supongo que otros tropezarán con esto también cuando intenten convertir todo bind, livey delegatellamen a on.
Felix Kling
44
Ah sí, y por supuesto, solo vemos esta respuesta después de ejecutar una búsqueda general para buscar y reemplazar desde .live>.on
ajbeaven
3
En mi opinión, la .onsintaxis es más lógica, ya que el oyente está realmente conectado al selector que proporciona. Cuando se desencadena el evento, jQuery atraviesa el DOM y ejecuta controladores donde se especifica (delegación de evento simple). .livesugirió que sucedió algo "mágico", y se dijo que adjuntaba controladores de eventos para "elementos futuros" que no era del todo cierto.
David Hellsing
1
@FelixKling eso es correcto - ¡Me encontré con esto también! Gracias
willdanceforfun 05 de
2
Para el motor de búsqueda: el método jQuery ".live ()" se deprecia desde v1.7 y se elimina en v1.9. Arregle sus scripts utilizando el método ".on ()" en su lugar. Sorprendentemente, esto también afecta al actual Microsoft jquery.unobtrusive-ajax.js v2.0.20710.0 (Microsoft tampoco actualizó sus scripts, así que ahora está roto).
Tony Wall
25

Además de la respuesta seleccionada,

Puerto jQuery.livea jQuery 1.9+ mientras espera que su aplicación migre. Agregue esto a su archivo JavaScript.

// 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;
        }
});

Nota: La función anterior no funcionará desde jQuery v3 comothis.selector se elimine.

O puede usar https://github.com/jquery/jquery-migrate

Vikrant Chaudhary
fuente
7

Acabo de encontrar una solución mejor que no implica la edición de código de terceros:

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

Instale el paquete jQuery Migrate NuGet en Visual Studio para solucionar todos los problemas de versiones. La próxima vez que Microsoft actualice sus discretos módulos de validación y AJAX, tal vez intente sin el script de migración nuevamente para ver si resolvieron el problema.

Como jQuery Migrate es mantenido por la Fundación jQuery, creo que este no es solo el mejor enfoque para las bibliotecas de terceros y también para recibir mensajes de advertencia para sus propias bibliotecas que detallen cómo actualizarlas.

Tony Wall
fuente
3

Además de las respuestas seleccionadas,

Si usa Visual Studio , puede usar Regex Reemplazar .
En Edición> Buscar y reemplazar> Reemplazar en archivos
o Ctrl + Shift + H

En la ventana emergente Buscar y reemplazar, configure estos campos

Encuentra qué: \$\((.*)\)\.live\((.*),
Reemplazar con: $(document.body).on($2,$1,
En las opciones de búsqueda, marque "Usar expresiones regulares"

Maykol Rypka
fuente
-1

jquery verision xxxjs editor abierto, encontrar jQuery.fn.extend

agregar código

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

Ejemplo: jquery-2.1.1.js -> línea 7469 (jQuery.fn.extend)

Vista de imágenes de ejemplo

Uğur Tosun
fuente