Ich frage mich, ob es Umstände gibt, unter denen .click(function {...});
besser als .live('click', function {...});
verwendet werden sollte.
Von dem, was ich erfahre, scheint die Live-Option eine bessere Option zu sein, und daher verwende ich sie unter fast allen Umständen anstelle des einfachen .click (), besonders wenn mein Code asynchron geladen wird.
EDIT: Ein weiterer Teil dieser Frage. Wenn ich das gesamte Javascript asynchron lädt, werden alle noch im Dom vorhandenen Elemente von .click übernommen. Recht?
Es kann vorkommen, dass Sie den Click-Handler explizit nur vorhandenen Objekten zuweisen und neue Objekte anders behandeln möchten. Aber im Allgemeinen funktioniert Live nicht immer. Es funktioniert nicht mit verketteten jQuery-Anweisungen wie:
$(this).children().live('click',doSomething);
Es ist eine Auswahl erforderlich, um ordnungsgemäß zu funktionieren, da Ereignisse den DOM-Baum aufblähen.
Edit: Jemand hat das gerade bestätigt, also schauen die Leute es immer noch an. Ich sollte darauf hinweisen, dass live
und bind
beide veraltet sind. Sie können beides mit .on()
ausführen, wobei IMO eine viel klarere Syntax ist. bind
ersetzen:
$(selector).on('click', function () {
...
});
und live
ersetzen:
$(document).on('click', selector, function () {
...
});
Anstelle von $(document)
können Sie jedes jQuery-Objekt verwenden, das alle Elemente enthält, die Sie mit den Klicks überwachen. Das entsprechende Element muss jedoch vorhanden sein, wenn Sie es aufrufen.
(Anmerkung 29/08/2017:live
wurde vor vielen Versionen veraltet und in v1.9 entfernt. delegate
wurde in v3.0 nicht mehr empfohlen. In beiden Fällen verwenden Sie stattdessen die Delegierungssignatur von on
unten].)
live
geschieht, indem das Ereignis erfasst wird, wenn es vom DOM bis zum Dokumentenstamm hinaufgesprudelt wird und dann das Quellelement betrachtet wird. click
geschieht, indem das Ereignis auf dem Element selbst erfasst wird. Wenn Sie also live
verwenden und eines der Vorfahrenelemente das Ereignis direkt einhakt (und verhindert, dass es weiterhin blubbert), wird das Ereignis niemals auf Ihrem Element angezeigt. Während normalerweise das Element, das dem Ereignis am nächsten ist (Klick oder ähnliches), zuerst angefasst wird, kann dies durch die Mischung von live
- und Nicht-live
-Ereignissen auf subtile Weise geändert werden.
Zum Beispiel:
jQuery(function($) {
$('span').live('click', function() {
display("<tt>live</tt> caught a click!");
});
$('#catcher').click(function() {
display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
<div>
<span>Click me</span>
<span>or me</span>
<span>or me</span>
<div>
<span>I'm two levels in</span>
<span>so am I</span>
</div>
<div id='catcher'>
<span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span>me too</span>
</div>
</div>
<!-- Using an old version because `live` was removed in v1.9 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
Ich würde empfehlen, delegate
über live
zu verwenden, wenn Sie können, damit Sie den Umfang gründlicher steuern können. Mit delegate
steuern Sie das Wurzelelement, das das Bubbling-Ereignis erfasst (z. B. live
ist im Grunde delegate
, wobei der Dokumentstamm als Stamm verwendet wird). Es wird außerdem empfohlen, (wenn möglich) zu vermeiden, dass delegate
oder live
mit der nicht delegierten, nicht Live-Ereignisbehandlung interagieren.
Einige Jahre später würden Sie weder live
noch delegate
verwenden. Sie würden die Delegierungssignatur von on
verwenden, aber das Konzept ist immer noch dasselbe: Das Ereignis hängt von dem Element ab, auf dem Sie on
aufgerufen haben, wird jedoch nur ausgelöst, wenn die Nachkommen mit der Auswahl hinter dem Namen des Ereignisses übereinstimmen:
jQuery(function($) {
$(document).on('click', 'span', function() {
display("<tt>live</tt> caught a click!");
});
$('#catcher').click(function() {
display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
<div>
<span>Click me</span>
<span>or me</span>
<span>or me</span>
<div>
<span>I'm two levels in</span>
<span>so am I</span>
</div>
<div id='catcher'>
<span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span>me too</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Alle Objekte, die mit dem .click verbunden wären, müssen vorhanden sein, wenn Sie das Ereignis festlegen.
Beispiel: (in Pseudo-Code) kann der Anhang beispielsweise $("body").append()
sein
append('<div id="foo" class="something">...</div>');
$("div.something").click(function(){...});
append('<div id="bar" class="something">...</div>');
Click funktioniert für Foo, aber nicht für Bar
Beispiel2:
append('<div id="foo" class="something">...</div>');
$("div.something").live("click",function(){...});
append('<div id="bar" class="something">...</div>');
klick funktioniert für foo und bar
Mit .live ('click' ...) können Sie dynamisch weitere Objekte hinzufügen, nachdem Sie das Ereignis erstellt haben, und das Klickereignis funktioniert weiterhin.
"live" wird benötigt, wenn Sie Code dynamisch generieren .. _. Schauen Sie sich das folgende Beispiel an:
$("#div1").find('button').click(function() {
$('<button />')
.text('BUTTON')
.appendTo('#div1')
})
$("#div2").find('button').live("click", function() {
$('<button />')
.text('BUTTON')
.appendTo('#div2')
})
button {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="div1">
<button>Click</button>
</div>
<div id="div2">
<button>Live</button>
</div>
ohne "live" tritt das Klickereignis nur beim Klicken auf die erste Schaltfläche auf, bei "Live" tritt das Klickereignis auch für die dynamisch erzeugten Schaltflächen auf
Verwenden Sie immer click
, wenn Sie Elemente nicht dynamisch hinzufügen.
live
fügt einen Ereignis-Listener zum Dokumentstamm hinzu und wartet auf gesprudelte Ereignisse. Eine Alternative ist delegate
, die genauso funktioniert, den Event-Handler jedoch an das angegebene Element bindet.
Auf diese Weise muss das Ereignis nicht das gesamte DOM sprudeln und wird früher erfasst.
.live () wird verwendet, wenn Elemente nach dem ersten Laden der Seite hinzugefügt werden. Angenommen, Sie haben eine Schaltfläche, die durch einen Aufruf von AJAX hinzugefügt wird, nachdem die Seite geladen wurde. Diese neue Schaltfläche kann nicht mit .click () aufgerufen werden, daher müssen Sie .live ('click') verwenden.
Da "live" Ereignisse für zukünftige Elemente behandelt, die der aktuellen Auswahl entsprechen, können Sie einen Klick auswählen, da dies nicht der Fall sein soll. Sie möchten nur die aktuell ausgewählten Elemente behandeln.
Ich vermute auch (obwohl es keine Beweise gibt), dass die Verwendung von "Klick" auf "Live" ein wenig effizient ist.
Lee
Aus dem, was ich verstehe, ist der Hauptunterschied, dass live () ein Auge für neue DOM-Elemente hat, die zu dem ausgewählten Selektor passen, während click () (oder bind ('click')) den Event-Hook anhängt und fertig ist.
Angesichts der Tatsache, dass ein Großteil Ihres Codes asynchron geladen wird, wird die Verwendung von live () Ihren Lebensalltag einfacher machen. Wenn Sie den von Ihnen geladenen Code nicht genau kennen, aber wissen, welche Art von Elementen Sie hören, ist die Verwendung dieser Funktion absolut sinnvoll.
In Bezug auf die Leistungssteigerung besteht eine Alternative zur Verwendung von live () darin, eine Callback-Funktion AJAX zu implementieren, um die Event-Hooks neu zu verknüpfen.
var ajaxCallback = function(){
$('*').unbind('click');
$('.something').bind('click', someFunction);
$('.somethingElse').bind('click', someOtherFunction);
}
Sie müssen Ihre Event-Hooks im Auge behalten und sicherstellen, dass diese Funktion die richtigen Events erneut bindet.
p.s. Mit den Ajax-Methoden .get (), .post (), .load () und .ajax () können Sie eine Callback-Funktion angeben.
denken Sie daran, dass "live" für "jQuery 1.3" oder höher verwendet wird
in Version "jQuery 1.4.3" oder höher wird "Delegate" verwendet
und Version "jQuery 1.7 +" oder höher wird "on" verwendet
$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+
Seit jQuery 1.7 ist die .live () -Methode veraltet.
check http://api.jquery.com/live/
Viele Grüße, Fernando
Wenn Sie Code vereinfachen müssen, ist Live in den meisten Fällen besser. Wenn Sie die beste Leistung erzielen möchten, ist der Delegat immer besser als Live. bind (klicken) vs Delegat ist nicht so einfach Frage (wenn Sie viele ähnliche Elemente haben, wird Delegat besser sein).
Neben T.J. Crowders antworten , ich habe einige weitere Handler hinzugefügt - einschließlich des neueren .on(...)
-Handlers für das Snippet, damit Sie sehen können, welche Ereignisse verborgen werden und welche nicht.
Ich fand auch, dass .live()
nicht nur veraltet ist, sondern seit jQuery 1.9.x gelöscht wurde. Aber die anderen, d.h. .click
, .delegate
.undelegate
und .on
/.off
sind noch da.
Beachten Sie auch, dass zu diesem Thema mehr über _/hier auf Stackoverflow diskutiert wird.
Wenn Sie älteren Code, der auf .live basiert, reparieren müssen, aber eine neue Version von jQuery (> 1.8.3) verwenden möchten, können Sie dies mit diesem Snippet beheben:
// fix if legacy code uses .live, but you want to user newer jQuery library
if (!$.fn.live) {
// in this case .live does not exist, emulate .live by calling .on
$.fn.live = function(events, handler) {
$(this).on(events, null, {}, handler);
};
}
Mit dem folgenden Snippet, einer Erweiterung des T.J.-Skripts, möchten Sie sofort ausprobieren, was passiert, wenn Sie mehrere Handler binden.
jQuery(function($) {
// .live connects function with all spans
$('span').live('click', function() {
display("<tt>live</tt> caught a click!");
});
// --- catcher1 events ---
// .click connects function with id='catcher1'
$('#catcher1').click(function() {
display("Click Catcher1 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// --- catcher2 events ---
// .click connects function with id='catcher2'
$('#catcher2').click(function() {
display("Click Catcher2 caught a click and prevented <tt>live</tt>, <tt>delegate</tt> and <tt>on</tt> from seeing it.");
return false;
});
// .delegate connects function with id='catcher2'
$(document).delegate('#catcher2', 'click', function() {
display("Delegate Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// .on connects function with id='catcher2'
$(document).on('click', '#catcher2', {}, function() {
display("On Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// --- catcher3 events ---
// .delegate connects function with id='catcher3'
$(document).delegate('#catcher3', 'click', function() {
display("Delegate Catcher3 caught a click and <tt>live</tt> and <tt>on</tt> can see it.");
return false;
});
// .on connects function with id='catcher3'
$(document).on('click', '#catcher3', {}, function() {
display("On Catcher3 caught a click and and <tt>live</tt> and <tt>delegate</tt> can see it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
<!-- with JQuery 1.8.3 it still works, but .live was removed since 1.9.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
<style>
span.frame {
line-height: 170%; border-style: groove;
}
</style>
<div>
<span class="frame">Click me</span>
<span class="frame">or me</span>
<span class="frame">or me</span>
<div>
<span class="frame">I'm two levels in</span>
<span class="frame">so am I</span>
</div>
<div id='catcher1'>
<span class="frame">#1 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
<div id='catcher2'>
<span class="frame">#2 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
<div id='catcher3'>
<span class="frame">#3 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
</div>