Was ist der Unterschied zwischen "on" und "live" oder "bind"?


172

In jQuery v1.7 wurde eine neue Methode onhinzugefügt. Aus der Dokumentation:

'Die .on () -Methode hängt Ereignishandler an die aktuell ausgewählte Gruppe von Elementen im jQuery-Objekt an. Ab jQuery 1.7 bietet die .on () -Methode alle Funktionen, die zum Anhängen von Ereignishandlern erforderlich sind. '

Was ist der Unterschied zu liveund bind?



Hatte vor der Frage nach so etwas gesucht und es nicht geschafft. Vielen Dank!
Diego

Antworten:


329

on()ist ein Versuch, die meisten Ereignisbindungsfunktionen von jQuery in einer zusammenzuführen. Dies hat den zusätzlichen Vorteil, die Ineffizienzen aufzuräumen mit livevs delegate. In zukünftigen Versionen von jQuery, werden diese Methoden entfernt und nur onund onewerden bleiben.

Beispiele:

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

Intern ordnet jQuery alle diese Methoden und Shorthand Event Handler-Setter der on()Methode zu, was weiter darauf hinweist, dass Sie diese Methoden von nun an ignorieren und nur Folgendes verwenden sollten 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 );
},

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


Wie @JamWaffles sagte die verständlichste Antwort. Würden Sie bitte den Vergleich zwischen on und delegate hinzufügen, um die Antwort zu vervollständigen? Vielen Dank!
Diego

lols, du hast die jquery-Quelle 4 Sekunden vor mir hinzugefügt: D Übrigens ist der äquivalente Live-Kontext document, nicht document.body
Esailija,

1
Möglicherweise möchten Sie stattdessen auf das Tag 1.7 verweisen, andernfalls kann Ihr Link bei zukünftigen Änderungen ungültig werden (nicht auf den richtigen Speicherort verweisen): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);sollte sein$(document.body).delegate(".mySelector", "click", fn);
Sonny

2
@dsdsdsdsd, off dient als generischer Ersatz für Unbind, Unlive und Undelegate.
Andy E

12

onist in der Natur sehr nah an delegate. Warum also nicht delegieren? Es ist, weil ones nicht alleine kommt. Es gibt die offMöglichkeit, das Ereignis aufzuheben und oneein Ereignis zu erstellen, das nur einmal ausgeführt werden soll. Dies ist das "Paket" einer neuen Veranstaltung.

Das Hauptproblem von liveist, dass es an "Fenster" angehängt wird und ein Klickereignis (oder ein anderes Ereignis) auf ein Element tief in der Seitenstruktur (das Dom) zwingt, um oben auf der Seite zu "sprudeln", um ein Ereignis zu finden Handler bereit, damit umzugehen. Auf jeder Ebene müssen alle Event-Handler überprüft werden. Dies kann sich schnell summieren, wenn Sie eine tiefe Imbrikation durchführen ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...).

So bind, wie click, wie andere Abkürzung Ereignis Bindemittel befestigen direkt auf das Ereignis - Ziel. Wenn Sie eine Tabelle mit beispielsweise 1000 Zeilen und 100 Spalten haben und jede der 100'000 Zellen ein Kontrollkästchen enthält, auf das Sie klicken möchten. Das Anhängen von 100'000 Ereignishandlern nimmt beim Laden der Seite viel Zeit in Anspruch. Das Erstellen eines einzelnen Ereignisses auf Tabellenebene und die Verwendung der Ereignisdelegierung ist um mehrere Größenordnungen effizienter. Das Ereignisziel wird zur Ereignisausführungszeit abgerufen. " this" wird die Tabelle sein, aber " event.target" wird Ihre übliche " this" in einer clickFunktion sein. Das Schöne daran onist, dass " this" immer das Ereignisziel ist und nicht der Container, an den es angehängt ist.


Kommt der Delegierte nicht mit undelegate?
DaveWalley

1
Jep. gute Beobachtung. Sie lernen jeden Tag;) (Der Doc hat sich seit 2011 stark verbessert)
Roselan

5

mit .onMethode ist es möglich , zu tun .live, .delegateund .bindmit gleicher Funktion , aber mit .live()nur .live()möglich ist (Ereignisse Dokument delegiert).

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 )

Ich kann dies direkt aus der jQuery-Quelle bestätigen:

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=== documentin den meisten Fällen


3

(Mein Eröffnungssatz war sinnvoller, bevor Sie die Frage geändert haben. Ursprünglich hatten Sie gesagt: "Was ist der Unterschied zu live?")

onist mehr wie delegateals es ist live, es ist im Grunde eine einheitliche Form von bindund delegate(in der Tat sagte das Team, sein Zweck sei "... alle Möglichkeiten zum Anhängen von Ereignissen an ein Dokument zu vereinheitlichen ..." ).

liveist grundsätzlich on(oder delegate) dem gesamten Dokument beigefügt. Es ist ab Version 1.7 zugunsten der Verwendung von onoder veraltetdelegate . Ich vermute, dass wir in Zukunft nur Code verwenden onwerden, anstatt bindoder delegate(oder live) ...

In der Praxis können Sie also:

  1. Verwenden Sie onwie bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
    
  2. Verwenden Sie onlike delegate(Ereignisdelegierung, die in einem bestimmten Element verwurzelt ist):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
    
  3. Verwenden Sie onlike live(Ereignisdelegation im Dokument verwurzelt):

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

1
Auf der von mir verlinkten Seite heißt es: "Wenn neuer HTML-Code in die Seite eingefügt wird, wählen Sie die Elemente aus und hängen Sie Ereignishandler an, nachdem der neue HTML-Code auf der Seite platziert wurde. Oder verwenden Sie delegierte Ereignisse, um einen Ereignishandler anzuhängen, wie im Folgenden beschrieben." . Also weiter ist eher binden, nicht leben. Habe ich recht?
Diego

@Diego: onist eine Kombination aus bindund delegate, und wie gesagt, nicht sehr ähnlich live. Sie können onlike verwenden bind(einen Handler direkt an ein Element anhängen) oder onlike verwenden delegate(einen Handler an ein Element anhängen, aber das Ereignis nur auslösen, wenn das tatsächlich angeklickte Element mit einem Selektor übereinstimmt und als ob dieses Element dasjenige wäre, das das ist Ereignis ereignet am - z. B. Ereignisdelegation), oder Sie können es wie verwenden live( delegatemit dem Dokument als Stamm). Es ist die Ereignisdelegation, die es nützlich macht, wenn Sie Elemente dynamisch hinzufügen.
TJ Crowder

1
Das alte Live könnte auch wie ein Delegat verwendet werden: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );In der alten jQuery-Quelle wurde Live als allgemeiner Fall und Delegat als Sonderfall verwendet, was dies umso verwirrender machte, wenn Sie darüber nachdenken.
Esailija

@Esailija: Fair genug. Ich glaube nicht, dass dies die Verwendung ist, für die es bekannt wurde, weil sie delegateschnell hinzugefügt haben , aber immer noch. :-)
TJ Crowder


2

Es gibt keine für den grundlegenden Anwendungsfall. Diese beiden Linien sind funktional gleich

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

.on () kann auch Ereignisdelegierungen durchführen und wird bevorzugt.

.bind () ist jetzt eigentlich nur ein Alias ​​für .on (). Hier ist die Definition der Bindefunktion in 1.7.1

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

Die Idee zum Hinzufügen von .on () bestand darin, eine einheitliche Ereignis-API zu erstellen, anstatt mehrere Funktionen zum Binden von Ereignissen zu haben. .on () ersetzt .bind (), .live () und .delegate ().


0

Etwas, das Sie beachten sollten, wenn Sie die mit dem Element verknüpften Ereignishandler erhalten möchten - achten Sie darauf, an welches Element der Handler angehängt wurde!

Zum Beispiel, wenn Sie verwenden:

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

Sie erhalten die Ereignishandler mit:

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

Aber wenn Sie verwenden:

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

Sie erhalten die Ereignishandler mit:

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

(Im letzten Fall hat das relevante Ereignisobjekt den Selektor = ". mySelector")


eventsist sowieso undokumentiert und ich denke, es funktioniert nicht mehr in 1.9
John Dvorak

Richtig. In den neueren Versionen kann man _data anstelle von Daten verwenden. Die Antwort war eher der Unterschied im "Event-Besitzer" als die genaue Syntax für alte oder neue Versionen. Es gibt weitere Beiträge zur genauen Syntax für verschiedene JQuery-Versionen. Zum Beispiel stackoverflow.com/questions/2518421/…
Alexander
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.