¿Cuál es la diferencia entre `on` y` live` o `bind`?


172

En jQuery v1.7 , onse agregó un nuevo método . De la documentación:

'El método .on () adjunta controladores de eventos al conjunto de elementos actualmente seleccionado en el objeto jQuery. A partir de jQuery 1.7, el método .on () proporciona toda la funcionalidad necesaria para adjuntar controladores de eventos '.

¿Cuál es la diferencia con livey bind?



Había buscado algo así antes de preguntar y no tuve éxito. ¡Gracias!
Diego

Respuestas:


329

on()es un intento de fusionar la mayoría de las funciones de enlace de eventos de jQuery en una sola. Esto tiene la ventaja añadida de poner en orden las ineficiencias con livevs delegate. En futuras versiones de jQuery, estos métodos serán eliminados y solamente ony oneserán dejados.

Ejemplos:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

Internamente, jQuery asigna todos estos métodos y configuradores de controladores de eventos abreviados al on()método, lo que indica que debe ignorar estos métodos de ahora en adelante y simplemente usar on:

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

Ver https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 .


Como @JamWaffles dijo la respuesta más comprensible. ¿Podría agregar la comparación entre encendido y delegado para completar la respuesta? ¡Gracias!
Diego

lols, agregaste la fuente jquery 4 segundos antes que yo: D btw live, el contexto equivalente es document, not document.body
Esailija

1
Es posible que desee hacer referencia a la etiqueta 1.7, de lo contrario, los cambios futuros pueden invalidar su enlace (no apuntar a la ubicación correcta): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);debería ser$(document.body).delegate(".mySelector", "click", fn);
Sonny

2
@dsdsdsdsd, off sirve como el reemplazo genérico para desvincular, deshacer y deshacer.
Andy E

12

onestá en la naturaleza muy cerca de delegate. Entonces, ¿por qué no usar delegado? Es porque onno viene solo. hay off, para desvincular un evento y onecrear un evento que se ejecutará solo una vez. Este es el "paquete" de un nuevo evento.

El problema principal livees que se adhiere a la "ventana", forzando un evento de clic (u otro evento) en un elemento en el interior de la estructura de la página (dom), para "subir" a la parte superior de la página para encontrar un evento controlador dispuesto a lidiar con eso. En cada nivel, todos los controladores de eventos deben verificarse, esto puede sumar rápidamente, si realiza una imbricación profunda ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Entonces, bindcomo click, como otras carpetas de eventos de acceso directo, se adjuntan directamente al destino del evento. Si tiene una tabla de, digamos, 1000 líneas y 100 columnas, y cada una de las 100'000 celdas incluye una casilla de verificación en la que desea hacer clic. Adjuntar 100.000 controladores de eventos llevará mucho tiempo en la carga de la página. Crear un solo evento a nivel de tabla y usar la delegación de eventos es más eficiente en varios órdenes de magnitud. El objetivo del evento se recuperará en el momento de la ejecución del evento. " this" será la tabla, pero " event.target" será su habitual " this" en una clickfunción. Ahora lo bueno ones que " this" siempre será el destino del evento, y no el contenedor al que está conectado.


¿Delegado no viene con undelegate?
DaveWalley

1
Sip. buen manchado.
Aprendes

5

con el .onmétodo es posible hacerlo .live, .delegatey .bindcon la misma función pero con .live()solo .live()es posible (delegar eventos al documento).

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

Puedo confirmar esto directamente desde la fuente jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

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

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

jQuery (this.context)? this.context=== documenten la mayoría de los casos


3

(Mi oración de apertura tenía más sentido antes de que cambiaras la pregunta. Originalmente habías dicho "¿Cuál es la diferencia live?")

ones más parecido delegatea lo que es live, es básicamente una forma unificada de bindy delegate(de hecho, el equipo dijo que su propósito es "... unificar todas las formas de adjuntar eventos a un documento ..." ).

liveestá básicamente on(o delegate) adjunto al documento en su conjunto. Está en desuso a partir de v1.7 a favor de usar ono delegate. En el futuro, sospecho que veremos el código usando onúnicamente, en lugar de usar bindo delegate(o live) ...

Entonces, en la práctica, puedes:

  1. Usar oncomo bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
    
  2. Use onlike delegate(delegación de evento enraizada en un elemento dado):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
    
  3. Use onlike live(delegación de evento enraizada en el documento):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
    

1
En la página que vinculé, dice "Si se está inyectando un nuevo HTML en la página, seleccione los elementos y adjunte los controladores de eventos después de que el nuevo HTML se coloque en la página. O use eventos delegados para adjuntar un controlador de eventos, como se describe a continuación". . Así es más probable que se una, no se viva Estoy en lo cierto?
Diego

@Diego: ones una combinación de bindy delegate, como dije, no me gusta mucho live. Puede usar onlike bind(adjuntar un controlador directamente a un elemento), o puede usar onlike delegate(adjuntar un controlador a un elemento, pero dispare el evento solo si el elemento real al hacer clic coincide con un selector, y como si ese elemento fuera el que el el evento ocurrió en, por ejemplo, delegación de evento), o puede usarlo como live( delegateusando el documento como raíz). Es la delegación de eventos lo que lo hace útil si agrega elementos dinámicamente.
TJ Crowder

1
el viejo live también podría usarse como delegado: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );En realidad, en la antigua fuente jQuery usaban live como el caso general y delegar como un caso especial, lo que hizo que esto fuera aún más confuso cuando lo piensas.
Esailija

@Esailija: Bastante justo. No creo que ese sea el uso por el que se hizo conocido, porque agregaron delegaterápidamente, pero aún así. :-)
TJ Crowder


2

No hay uno para el caso de uso básico. Estas dos líneas son funcionalmente iguales.

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () también puede hacer delegación de eventos, y es preferible.

.bind () es en realidad solo un alias para .on () ahora. Aquí está la definición de la función de enlace en 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

La idea para agregar .on () era crear una API de evento unificada, en lugar de tener múltiples funciones para el evento de enlace; .on () reemplaza .bind (), .live () y .delegate ().


0

Algo que debe tener en cuenta si desea obtener los controladores de eventos asociados con el elemento: ¡preste atención a qué elemento estaba conectado el controlador!

Por ejemplo, si usa:

$('.mySelector').bind('click', fn);

obtendrá los controladores de eventos usando:

$('.mySelector').data('events');

Pero si usas:

$('body').on('click', '.mySelector', fn);

obtendrá los controladores de eventos usando:

$('body').data('events');

(en el último caso, el objeto de evento relevante tendrá selector = ". mySelector")


eventsestá indocumentado de todos modos y creo que ya no funciona en 1.9
John Dvorak

Correcto. Uno puede usar _data en lugar de datos en las versiones más recientes. La respuesta fue sobre la diferencia en el "propietario del evento", más bien la sintaxis exacta para las versiones antiguas o nuevas. Hay otras publicaciones sobre la sintaxis exacta para diferentes versiones de JQuery. Por ejemplo stackoverflow.com/questions/2518421/…
Alexander
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.