Jaka jest różnica między „on” a „live” lub „bind”?

172

W jQuery v1.7 dodano nową metodę on. Z dokumentacji:

Metoda .on () dołącza procedury obsługi zdarzeń do aktualnie wybranego zestawu elementów w obiekcie jQuery. Od wersji jQuery 1.7 metoda .on () zapewnia wszystkie funkcje wymagane do dołączania programów obsługi zdarzeń. '

Jaka jest różnica między livei bind?

Diego
źródło
Szukałem czegoś takiego, zanim zapytałem, i nie udało się. Dzięki!
Diego

Odpowiedzi:

329

on()jest próbą połączenia większości funkcji wiązania zdarzeń jQuery w jedną. To ma dodatkowy bonus sprzątania nieefektywności z livevs delegate. W przyszłych wersjach jQuery te metody zostaną usunięte i tylko oni onepozostaną.

Przykłady:

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

Wewnętrznie jQuery mapuje wszystkie te metody i skrócone metody ustawiające programy obsługi zdarzeń na on()metodę, co dodatkowo wskazuje, że od teraz należy ignorować te metody i po prostu używać 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 );
},

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

Andy E.
źródło
Jak @JamWaffles powiedział, najbardziej zrozumiałą odpowiedź. Czy mógłbyś dodać porównanie między włączeniem a delegatem, aby uzupełnić odpowiedź? Dzięki!
Diego
lols, dodałeś źródło jquery 4 sekundy wcześniej: D btw ekwiwalentem na żywo jest dokument, a nie dokument.body
Esailija
1
Zamiast tego możesz odnieść się do tagu 1.7, w przeciwnym razie przyszłe zmiany mogą spowodować, że Twój link będzie nieprawidłowy (nie wskaże właściwej lokalizacji): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling
3
$(document.body).delegate("click", ".mySelector", fn);powinno być$(document.body).delegate(".mySelector", "click", fn);
Sonny
2
@dsdsdsdsd, off służy jako ogólny zamiennik dla unbind, unlive i undelegate.
Andy E
12

onjest w naturze bardzo blisko delegate. Dlaczego więc nie użyć delegata? To dlatego, onże nie przychodzi sam. istnieje off, aby usunąć powiązanie zdarzenia i oneutworzyć zdarzenie, które ma być wykonane tylko raz. To jest „pakiet” nowego wydarzenia.

Głównym problemem livejest to, że dołącza się do „okna”, wymuszając zdarzenie kliknięcia (lub inne zdarzenie) na elemencie znajdującym się głęboko w strukturze strony (dom), aby „unieść się” na górę strony w celu znalezienia zdarzenia opiekun chce się tym zająć. Na każdym poziomie wszystkie programy obsługi zdarzeń muszą zostać sprawdzone, może to szybko się sumować, jeśli wykonujesz głębokie imbrication ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Tak więc, bindpodobnie clickjak inne spoiwa skrótów zdarzeń dołączane są bezpośrednio do celu zdarzenia. Jeśli masz tabelę składającą się, powiedzmy, z 1000 wierszy i 100 kolumn, a każda ze 100 000 komórek zawiera pole wyboru, którego kliknięcie chcesz obsłużyć. Dołączenie 100 000 programów obsługi zdarzeń zajmie dużo czasu podczas ładowania strony. Tworzenie pojedynczego zdarzenia na poziomie tabeli i używanie delegowania zdarzeń jest o kilka rzędów wielkości bardziej wydajne. Cel zdarzenia zostanie pobrany w czasie wykonywania zdarzenia. „ this” będzie tabelą, ale „ event.target” będzie zwykłym „ this” w clickfunkcji. Teraz fajną rzeczą onjest to, że „ this” zawsze będzie celem zdarzenia, a nie kontenerem, do którego jest dołączony.

roselan
źródło
Czy delegat nie jest dostarczany z cofniętym pełnomocnictwem?
DaveWalley
1
Tak. dobre wykrywanie. Uczysz się codziennie;) (Dokument znacznie się poprawił od 2011 r.)
roselan
5

przy użyciu .onmetody można to zrobić .live, .delegatei .bindprzy użyciu tej samej funkcji, ale .live()tylko przy użyciu .live()jest możliwe (delegowanie zdarzeń do dokumentu).

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 )

Mogę to potwierdzić bezpośrednio ze źródła 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=== documentw większości przypadków

Esailija
źródło
3

(Moje zdanie początkowe miało więcej sensu, zanim zmieniłeś pytanie. Pierwotnie powiedziałeś „Jaka jest różnica live?”)

onjest bardziej podobny delegateniż jest live, jest w zasadzie ujednoliconą formą bindi delegate(w rzeczywistości zespół powiedział, że jego celem jest „... ujednolicenie wszystkich sposobów dołączania wydarzeń do dokumentu ...” ).

livejest w zasadzie on(lub delegate) dołączony do dokumentu jako całości. Jest przestarzały od wersji 1.7 na korzyść używania onlub delegate. Podejrzewam, że w przyszłości zobaczymy kod wykorzystujący onwyłącznie, a nie bindlub delegate(lub live) ...

W praktyce możesz więc:

  1. Użyj onjak bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Użyj onlike delegate(delegacja zdarzenia zakorzeniona w danym elemencie):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. Użyj onlike live(delegacja zdarzenia zakorzeniona w dokumencie):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
TJ Crowder
źródło
1
Na stronie, do której utworzyłem łącze, jest napisane „Jeśli nowy kod HTML jest wprowadzany do strony, wybierz elementy i dołącz procedury obsługi zdarzeń po umieszczeniu nowego kodu HTML na stronie. Lub użyj delegowanych zdarzeń, aby dołączyć procedurę obsługi zdarzeń, jak opisano poniżej”. . Więc bardziej prawdopodobne jest związanie, a nie życie. Czy mam rację?
Diego
@Diego: onto kombinacja bindi delegate, i jak powiedziałem, niezbyt podobna live. Możesz użyć onlike bind(dołącz procedurę obsługi bezpośrednio do elementu) lub możesz użyć onlike delegate(dołącz procedurę obsługi do elementu, ale uruchom zdarzenie tylko wtedy, gdy kliknięty element pasuje do selektora i tak jakby ten element był tym zdarzenie miało miejsce - np. delegacja zdarzenia), lub możesz go użyć w podobny sposób live( delegateużywając dokumentu jako root). To delegacja zdarzenia sprawia, że ​​jest przydatna, jeśli dodajesz elementy dynamicznie.
TJ Crowder
1
stary live może być również używany jako delegate: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );Właściwie w starym źródle jQuery używali live jako przypadku ogólnego i delegata jako przypadku specjalnego, co czyniło to tym bardziej zagmatwanym, kiedy się nad tym zastanowić.
Esailija,
@Esailija: W porządku. Nie sądzę, że to jest zastosowanie, z którego jest znany, ponieważ dodali delegateszybko, ale nadal. :-)
TJ Crowder
2

live jest teraz skrótem do .on ()

//from source http://code.jquery.com/jquery-1.7.js
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

również ten post może być dla Ciebie przydatny http://blog.jquery.com/2011/11/03/jquery-1-7-released/

doochik
źródło
2

Nie ma jednego dla podstawowego przypadku użycia. Te dwie linie są funkcjonalnie takie same

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

.on () może również delegować zdarzenia i jest preferowane.

.bind () jest teraz po prostu aliasem dla .on (). Oto definicja funkcji bind w wersji 1.7.1

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

Pomysł na dodanie .on () polegał na stworzeniu ujednoliconego interfejsu API zdarzeń, zamiast posiadania wielu funkcji do wiązania zdarzeń; .on () zastępuje .bind (), .live () i .delegate ().

Dan
źródło
0

Coś, o czym powinieneś wiedzieć, jeśli chcesz uzyskać obsługę zdarzeń skojarzonych z elementem - zwróć uwagę, do którego elementu została dołączona funkcja obsługi!

Na przykład, jeśli używasz:

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

otrzymasz programy obsługi zdarzeń za pomocą:

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

Ale jeśli używasz:

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

otrzymasz programy obsługi zdarzeń za pomocą:

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

(w ostatnim przypadku odpowiedni obiekt zdarzenia będzie miał selector = ". mySelector")

Alexander
źródło
eventsi tak jest nieudokumentowany i myślę, że już nie działa w 1.9
John Dvorak
Dobrze. W nowszych wersjach zamiast danych można użyć _data. Odpowiedź dotyczyła różnicy w „właścicielu zdarzenia”, a raczej dokładnej składni starej lub nowej wersji. Istnieją inne posty dotyczące dokładnej składni dla różnych wersji JQuery. Na przykład stackoverflow.com/questions/2518421/…
Alexander