Método jQuery .live() vs .on() para agregar un evento de clic después de cargar html dinámico

Resuelto Sean Thoman asked hace 12 años • 7 respuestas

Estoy usando jQuery v.1.7.1 donde el método .live() aparentemente está obsoleto.

El problema que tengo es que cuando cargo dinámicamente html en un elemento usando:

$('#parent').load("http://..."); 

Si intento agregar un evento de clic después, no registra el evento usando ninguno de estos métodos:

$('#parent').click(function() ...); 

o

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

¿Cuál es la forma correcta de lograr esta funcionalidad? Sólo parece funcionar con .live() para mí, pero no debería usar ese método. Tenga en cuenta que #child es un elemento cargado dinámicamente.

Gracias.

Sean Thoman avatar Jan 06 '12 08:01 Sean Thoman
Aceptado

Si desea que el controlador de clic funcione para un elemento que se carga dinámicamente, entonces configura el controlador de eventos en un objeto principal (que no se carga dinámicamente) y le asigna un selector que coincida con su objeto dinámico de esta manera:

$('#parent').on("click", "#child", function() {});

El controlador de eventos se adjuntará al #parentobjeto y cada vez que aparezca un evento de clic que se originó en #child, activará su controlador de clics. Esto se denomina manejo de eventos delegado (el manejo de eventos se delega a un objeto principal).

Se hace de esta manera porque puede adjuntar el evento al #parentobjeto incluso cuando el #childobjeto aún no existe, pero cuando más tarde existe y se hace clic en él, el evento de clic aparecerá en el #parentobjeto, verá que se originó #childy hay un controlador de eventos para hacer clic #childy activar su evento.

jfriend00 avatar Jan 06 '2012 01:01 jfriend00

Prueba esto:

$('#parent').on('click', '#child', function() {
    // Code
});

De la $.on()documentación:

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

Su #childelemento no existe cuando $.on()lo invoca, por lo que el evento no está vinculado (a diferencia de $.live()). #parent, sin embargo, existe , por lo que vincular el evento a eso está bien.

El segundo argumento en mi código anterior actúa como un 'filtro' que solo se activa si el evento subió #parentdesde #child.

Bojangles avatar Jan 06 '2012 01:01 Bojangles

$(document).on('click', '.selector', function() { /* do stuff */ });

EDITAR: Estoy proporcionando un poco más de información sobre cómo funciona esto, porque... palabras. Con este ejemplo, estará colocando un oyente en todo el documento.

Cuando clickcoincide con cualquier elemento .selector, el evento se propaga al documento principal, siempre y cuando no haya otros oyentes que llamen al event.stopPropagation()método, lo que superaría la propagación de un evento a los elementos principales.

En lugar de vincularse a un elemento o conjunto de elementos específico, está escuchando cualquier evento proveniente de elementos que coincidan con el selector especificado. Esto significa que puede crear un oyente, una vez, que coincidirá automáticamente con los elementos existentes actualmente, así como con cualquier elemento agregado dinámicamente.

Esto es inteligente por varias razones, incluido el rendimiento y la utilización de la memoria (en aplicaciones a gran escala).

EDITAR:

Obviamente, el elemento principal más cercano que pueda escuchar es mejor, y puede usar cualquier elemento en lugar de él, documentsiempre y cuando los elementos secundarios que desee monitorear estén dentro de ese elemento principal... pero eso realmente no tiene nada que ver. con la pregunta.

Larry Williamson avatar Jan 06 '2012 01:01 Larry Williamson

El equivalente de .live() en 1.7 se ve así:

$(document).on('click', '#child', function() ...); 

Básicamente, mire el documento para ver los eventos de clic y filtrelos por #niño.

Jared avatar Jan 06 '2012 01:01 Jared

Sé que es un poco tarde para una respuesta, pero creé un polyfill para el método .live(). Lo probé en jQuery 1.11 y parece funcionar bastante bien. Sé que se supone que debemos implementar el método .on() siempre que sea posible, pero en proyectos grandes, donde no es posible convertir todas las llamadas .live() a llamadas .on() equivalentes por cualquier motivo, lo siguiente podría trabajar:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

Simplemente inclúyalo después de cargar jQuery y antes de llamar a live().

NSV avatar May 07 '2014 16:05 NSV