Alle untergeordneten Knoten von einem übergeordneten Knoten entfernen?

78

Ich habe eine Liste, ich möchte nur alle untergeordneten Knoten daraus entfernen. Was ist der effizienteste Weg mit jquery? Das habe ich:

<ul id='foo'>
  <li>a</li>
  <li>b</li>
</ul>

var thelist = document.getElementById("foo");   
while (thelist.hasChildNodes()){
    thelist.removeChild(thelist.lastChild);
}

Gibt es eine Verknüpfung, anstatt jedes Element einzeln zu entfernen?

----------- Bearbeiten ----------------

An jedes Listenelement sind einige Daten angehängt, und ein Klick-Handler wie folgt:

$('#foo').delegate('li', 'click', function() {
    alert('hi!');
});

// adds element to the list at runtime
function addListElement() {
    var element = $('<li>hi</hi>');
    element.data('grade', new Grade());
}

Möglicherweise füge ich auch Schaltflächen pro Listenelement hinzu. Es sieht also so aus, als ob leer () der richtige Weg ist, um sicherzustellen, dass keine Speicherlecks auftreten.

user246114
quelle
In welchen Begriffen effizient? Leistung, Lesbarkeit?
Gumbo
Wie wichtig ist das Gedächtnis neben den Fragen von @ Gumbo? Haben diese Elemente Ereignishandler gebunden?
Nick Craver
In Anbetracht der aktualisierten Antwort, ja .empty()wäre der Weg zu gehen, zu löschen , die Daten aus , $.cachedass element.data('grade', new Grade());fügt in.
Nick Craver
Ja, es sind Daten gebunden, und möglicherweise sind Event-Handler gebunden (im Moment verwende ich nur einen Delegaten für alle Elemente).
user246114
@ NickCraver Ich spucke nur hier, aber sogar mit JS, können Sie tuntheList.innerHTML=""
John Strood

Antworten:

184

Sie können .empty()wie folgt verwenden :

$("#foo").empty();

Aus den Dokumenten :

Entfernen Sie alle untergeordneten Knoten der Gruppe übereinstimmender Elemente aus dem DOM.

Nick Craver
quelle
6
Ebenfalls erwähnenswert (aus Dokumenten) Um Speicherverluste zu vermeiden, entfernt jQuery andere Konstrukte wie Daten- und Ereignishandler aus den untergeordneten Elementen, bevor die Elemente selbst entfernt werden.
user113716
1
@patrick - +1, ein weiterer Grund, diesen Weg über den oft empfohlenen zu gehen .html(''), da überhaupt keine Daten auf dem Element gespeichert sind. Viele Menschen vergessen das Leck, das verursacht.
Nick Craver
1
+1 Wenn Sie sicher sind, dass keine Ereignisse an die Kinder des Elternteils gebunden wurden, $("#foo")[0].innerHTML="";ist dies schneller. Achten Sie nur darauf, dass Sie beim Entfernen von Elementen auf diese Weise keine Speicherlecks verursachen (es wird empty()bereits sehr darauf geachtet, dass dies nicht geschieht, insbesondere im IE).
David Murdoch
@ David - Die Ereignisse wären in allen Browsern ein Problem, aber der gute Punkt, IE hat andere Speicherprobleme, viele von ihnen. Da die Ereignisse tatsächlich zusammen $.cachemit den restlichen Daten gespeichert werden, werden sie bei den HTML-Einstellungsaufrufen nicht entfernt.
Nick Craver
1
Ok, aktualisierte Frage, ja, ich habe einige Daten mit jedem Element verknüpft, also sieht es so aus, als ob leer () der richtige Weg ist.
user246114
5

Ein anderer Benutzer schlug vor,

.empty()

ist gut genug, weil es alle untergeordneten Knoten (sowohl Tag-Knoten als auch Textknoten) UND alle Arten von Daten entfernt, die in diesen Knoten gespeichert sind. Weitere Informationen finden Sie in der leeren Dokumentation zur JQuery-API .

Wenn Sie Daten behalten möchten, wie z. B. Ereignishandler, sollten Sie diese verwenden

.detach()

wie in der API-Trennungsdokumentation von JQuery beschrieben .

Die Methode .remove () könnte für ähnliche Zwecke nützlich sein.

Marco Ottina
quelle