/ / Element anhängen und entfernen zerstört alle Event-Handler in jquery? - Javascript, Abfrage

anhängendes Element und entfernen es alle Event-Handler in jquery zerstört? - Javascript, jQuery

Ok, ich erstelle ein Element, ordne einen Klick-Handler zu und hänge es an den Body an. Dann entferne ich es und hänge es erneut an und der Click-Handler funktioniert nicht mehr ???

Warum sollte das passieren?

var btn = $("<button>").text("hi").click(function(){console.log(3);});
var div = $("<div>");
div.append(btn);
$("body").append(div);
//click it now, it works..
div.html("");
div.append(btn);
// now button doesn"t work..

Warum passiert das und was kann ich tun, um es zu beheben?

Antworten:

6 für die Antwort № 1

Schon seit .html("") ist im Wesentlichen das Gleiche wie .empty()gilt (ab dem jQuery-Dokumente):

Um Speicherverluste zu vermeiden, entfernt jQuery andere Konstrukte wie z. B. Daten- und Ereignishandler aus den untergeordneten Elementen, bevor sie die Elemente selbst entfernen.

Wenn Sie Elemente entfernen möchten, ohne ihre Daten oder Ereignishandler zu zerstören (damit sie später wieder hinzugefügt werden können), verwenden Sie .detach() stattdessen.

Eine Option wäre zu verwenden Ereignisdelegierung. Dabei ist das Ereignis nicht direkt an das Ereignis gebunden button Es ist an ein konstantes übergeordnetes Element gebunden, das nicht entfernt wird.

Beispiel hier

$(document).on("click", "button", function () {
// ..
});

Wie oben erwähnt, wäre eine andere Option, die zu verwenden .detach() Methode um das Element aus dem DOM zu entfernen, ohne angehängte Ereignis-Listener zu entfernen.

Das .detach() Methode ist das gleiche wie .remove(), außer dass .detach() behält alle jQuery-Daten bei, die den entfernten Elementen zugeordnet sind. Diese Methode ist nützlich, wenn entfernte Elemente zu einem späteren Zeitpunkt wieder in das DOM eingefügt werden sollen.

Beispiel hier

div.find("button").detach();
div.append(btn);

2 für die Antwort № 2

setze dies nach dem zweiten div.append (btn); -> btn = $("button").text("hi").click(function(){console.log(3);});


2 für die Antwort № 3

Das ist eine sehr interessante Situation. Was passiert, wenn Sie löschen div mit html("") Methode. Schauen Sie sich an Quellcode und Sie werden sehen, dass intern jQuery-Aufrufe jQuery.cleanData(getAll(elem, false));. Diese Methode ist für das Entfernen aller dazugehörigen Elemente verantwortlich data Für alle untergeordneten Elemente, die bereits entfernt wurden. Dies ist wichtig, um Speicherlecks zu vermeiden.

Durch das Löschen von Daten werden auch Ereignisse entfernt, an die gebunden ist on (und ähnliche) Methoden, da diese Ereignishandler auch im internen Cache-Objekt gespeichert werden.

Also als Ergebnis, obwohl Sie den Inhalt der entfernt div, das btn Das Objekt befindet sich noch im Speicher, das zuvor daran gebundene Ereignis ist jedoch nicht mehr vorhanden.

Dies war die Erklärung des Problems. Die Lösung besteht darin, eine dedizierte Methode namens zu verwenden detach. Die Schaltfläche wird aus dem DOM entfernt, die Ereignisdaten bleiben jedoch erhalten, falls das Element später erneut angehängt wird.

// remove element but keep its data
btn.detach();

// append back
div.append(btn);

In solchen Situationen sollten Sie nicht verwenden html("").


2 für die Antwort № 4

Es passiert, weil Sie anrufen html() auf dem DIV, der die Schaltfläche enthält.

Wenn du anrufst html() mit einer leeren Zeichenfolge ruft es auf empty() im Inneren.
Berufung empty() Ein Element durchläuft alle Elemente in diesem Element und entfernt alle Daten und Ereignisse auf sichere Weise.

Es tut dies, indem es anruft jQuery.cleanData auf den button, der nochmal explizit aufruft jQuery.removeEvent, Entfernen aller Ereignisse auf der Schaltfläche.

Die Schaltfläche ist weiterhin in der Variablen gespeichert btnEs kann also erneut angehängt werden, hat jedoch alle Daten und damit verbundenen Ereignisse verloren, da das übergeordnete Element über Folgendes verfügte html("") rief es an.

Die Lösung ist zu verwenden detach() um das Element mit allen Daten zu entfernen undereignisse intakt, so dass sie erneut angehängt werden können, oder sie können das ereignis an ein übergeordnetes element anhängen, das nicht entfernt wurde, oder sie können das element einfach ausblenden, im allgemeinen gibt es keinen grund, das element zu entfernen, nur um es erneut anzuhängen Es ist besser, es zu verstecken.

GEIGE