Qual è la differenza tra `on` e` live` o `bind`?


172

In jQuery v1.7 èon stato aggiunto un nuovo metodo . Dalla documentazione:

'Il metodo .on () collega i gestori di eventi all'insieme di elementi attualmente selezionato nell'oggetto jQuery. A partire da jQuery 1.7, il metodo .on () fornisce tutte le funzionalità necessarie per collegare i gestori di eventi. '

Qual è la differenza con livee bind?



Avevo cercato qualcosa del genere prima di chiedere e non ci riuscì. Grazie!
Diego,

Risposte:


329

on()è un tentativo di unire la maggior parte delle funzioni di associazione di eventi di jQuery in una. Questo ha il vantaggio di mettere in ordine le inefficienze con livevs delegate. Nelle versioni future di jQuery, questi metodi verranno rimossi e solo one onerimarranno.

Esempi:

// 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 associa tutti questi metodi e setter del gestore di eventi abbreviati al on()metodo, indicando ulteriormente che dovresti ignorare questi metodi da ora in poi e usare solo 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 );
},

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


Come @JamWaffles ha detto la risposta più comprensibile. Vorresti aggiungere il confronto tra on e delegate per completare la risposta? Grazie!
Diego,

lols, hai aggiunto la fonte jquery 4 secondi prima di me: D btw il contesto equivalente dal vivo è document, non document.body
Esailija

1
Potresti invece fare riferimento al tag 1.7, altrimenti modifiche future potrebbero rendere il tuo link non valido (non puntare alla posizione giusta): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);dovrebbe essere$(document.body).delegate(".mySelector", "click", fn);
Sonny,

2
@dsdsdsdsd, off funge da sostituto generico per unbind, unlive e undelegate.
Andy E

12

onè in natura molto vicino delegate. Quindi perché non usare delegate? È perché onnon viene da solo. c'è off, per separare un evento e onecreare un evento da eseguire una sola volta. Questo è il "pacchetto" di un nuovo evento.

Il problema principale liveè che si attacca alla "finestra", forzando un evento clic (o altro evento) su un elemento in profondità nella struttura della pagina (la dom), per "passare il mouse" nella parte superiore della pagina per trovare un evento gestore disposto a gestirlo. Ad ogni livello, tutti i gestori di eventi devono essere controllati, questo può sommarsi rapidamente, se si esegue l'imbrication profonda ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Quindi, bindcome click, come altri raccoglitori di eventi di collegamento, si collegano direttamente al target dell'evento. Se hai una tabella di, diciamo, 1000 righe e 100 colonne, e ognuna delle 100'000 celle include una casella di controllo che fai clic che vuoi gestire. Il collegamento di 100.000 gestori di eventi richiederà molto tempo al caricamento della pagina. La creazione di un singolo evento a livello di tabella e l'utilizzo della delega degli eventi è più efficiente di diversi ordini di grandezza. Il target dell'evento verrà recuperato al momento dell'esecuzione dell'evento. " this" sarà il tavolo, ma " event.target" sarà il tuo solito " this" in una clickfunzione. Ora la cosa bella onè che " this" sarà sempre il target dell'evento e non il contenitore a cui è collegato.


Il delegato non arriva con un delegato?
DaveWalley,

1
Sì. buon avvistamento. Si impara ogni giorno;) (Il documento è notevolmente migliorato dal 2011 tu)
Roselan,

5

con il .onmetodo è possibile fare .live, .delegatee .bindcon la stessa funzione ma con .live()solo .live()è possibile (delegare eventi 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 )

Posso confermare questo direttamente dalla fonte 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=== documentnella maggior parte dei casi


3

(La mia frase di apertura aveva più senso prima di cambiare la domanda. Inizialmente avevi detto "Qual è la differenza con live?")

onè più simile delegatedi come è live, è fondamentalmente una forma unificata di ( binde delegatein effetti, il team ha detto che il suo scopo è "... unificare tutti i modi di allegare eventi a un documento ..." ).

liveè sostanzialmente on(o delegate) allegato al documento nel suo insieme. È deprecato dalla v1.7 a favore dell'uso di ono delegate. Andando avanti, sospetto che vedremo il codice usare onsolo, anziché usare bindo delegate(o live) ...

Quindi, in pratica, puoi:

  1. Usa oncome bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Usa onlike delegate(delega dell'evento radicata in un determinato elemento):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. Usa oncome live(delegazione di eventi radicata nel documento):

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

1
Nella pagina che ho collegato dice "Se il nuovo HTML viene iniettato nella pagina, selezionare gli elementi e collegare i gestori di eventi dopo che il nuovo HTML è stato inserito nella pagina. Oppure, utilizzare gli eventi delegati per allegare un gestore di eventi, come descritto di seguito". . Quindi è più probabile che si leghi, non vivi. Ho ragione?
Diego,

@Diego: onè una combinazione di binde delegate, e come ho già detto, non molto simile live. Puoi usare onlike bind(collega un gestore direttamente a un elemento), oppure puoi usare onlike delegate(collega un gestore a un elemento, ma attiva l'evento solo se l'elemento reale selezionato fa clic su un selettore e come se quell'elemento fosse quello evento accaduto il - ad esempio, delega dell'evento), oppure puoi usarlo come live( delegateusando il documento come root). È la delega degli eventi che lo rende utile se si aggiungono elementi in modo dinamico.
TJ Crowder,

1
il vecchio live potrebbe anche essere usato come delegato: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );In realtà nella vecchia fonte jQuery usavano live come caso generale e delegano come caso speciale, il che ha reso tutto ciò ancora più confuso quando ci pensate.
Esailija,

@Esailija: abbastanza giusto. Non penso che sia l'uso per cui è stato conosciuto, perché sono stati aggiunti delegaterapidamente, ma comunque. :-)
TJ Crowder,


2

Non ce n'è uno per il caso d'uso di base. Queste due linee sono funzionalmente uguali

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

.on () può anche eseguire la delega di eventi ed è preferito.

.bind () è in realtà solo un alias per .on () ora. Ecco la definizione della funzione bind in 1.7.1

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

L'idea per l'aggiunta di .on () era quella di creare un'API di eventi unificata, anziché avere più funzioni per l'associazione di eventi; .on () sostituisce .bind (), .live () e .delegate ().


0

Qualcosa di cui dovresti essere consapevole se vuoi che i gestori di eventi siano associati all'elemento: presta attenzione a quale elemento era associato il gestore!

Ad esempio, se si utilizza:

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

otterrai i gestori di eventi usando:

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

Ma se usi:

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

otterrai i gestori di eventi usando:

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

(nell'ultimo caso l'oggetto evento rilevante avrà selector = ". mySelector")


eventsè comunque privo di documenti e penso che non funzioni più nell'1.9
John Dvorak,

Destra. È possibile utilizzare _data anziché i dati nelle versioni più recenti. La risposta era sulla differenza nel "proprietario dell'evento" piuttosto che sulla sintassi esatta per le versioni vecchie o nuove. Esistono altri post sulla sintassi esatta per diverse versioni di JQuery. Ad esempio stackoverflow.com/questions/2518421/…
Alexander,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.