Wie würde ich vorgehen, um alle untergeordneten Elemente eines DOM-Knotens in JavaScript zu entfernen?
Angenommen, ich habe den folgenden (hässlichen) HTML-Code:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
Und ich greife nach dem Knoten, den ich möchte:
var myNode = document.getElementById("foo");
Wie könnte ich die Kinder entfernen, foo
damit nur <p id="foo"></p>
noch übrig bleibt?
Könnte ich einfach tun:
myNode.childNodes = new Array();
oder sollte ich eine Kombination von verwenden removeElement
?
Ich möchte, dass die Antwort direkt bei DOM ist. Allerdings zusätzliche Punkte, wenn Sie in jQuery zusammen mit der Nur-DOM-Antwort auch eine Antwort angeben.
javascript
dom
Polaris878
quelle
quelle
innerHTML = ''
ist langsamer, aber ich denke nicht, dass es "falsch" ist. Alle Behauptungen von Speicherlecks sollten mit Beweisen belegt werden.Die derzeit akzeptierte Antwort ist falsch,
innerHTML
weil sie langsamer ist (zumindest in IE und Chrome), wie m93a richtig erwähnt.Chrome und FF sind mit dieser Methode erheblich schneller (wodurch angehängte Abfragedaten zerstört werden):
in einer fernen Sekunde für FF und Chrome und am schnellsten im IE:
InnerHTML zerstört Ihre Event-Handler nicht und bricht keine JQuery-Referenzen . Es wird auch als Lösung hier empfohlen: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML .
Die schnellste DOM-Manipulationsmethode (immer noch langsamer als die beiden vorherigen) ist das Entfernen von Bereichen. Bereiche werden jedoch erst in IE9 unterstützt.
Die anderen genannten Methoden scheinen vergleichbar zu sein, aber viel langsamer als innerHTML, mit Ausnahme des Ausreißers jquery (1.1.1 und 3.1.1), der erheblich langsamer ist als alles andere:
Beweis hier:
http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300https://jsperf.com/remove-all-child-elements-of-a- dom-node-in-javascript (Neue URL für den Neustart von jsperf, da das Bearbeiten der alten URL nicht funktioniert)Jsperfs "Per-Test-Loop" wird oft als "Per-Iteration" verstanden, und nur bei der ersten Iteration müssen Knoten entfernt werden, sodass die Ergebnisse bedeutungslos sind. Zum Zeitpunkt der Veröffentlichung waren Tests in diesem Thread falsch eingerichtet.
quelle
jQuery.cache
, was zu einem Speicherverlust führt, da die einzige verfügbare Referenz zum Verwalten dieser Daten auf den gerade zerstörten Elementen war.cloneNode
schaltet den Container aus, was bedeutet, dass Verweise auf den Container nicht gepflegt werden (jquery oder anderweitig). Im Cache von Jquery kann es sich lohnen, jquery zum Entfernen von Elementen zu verwenden, wenn Sie an jquery-Daten angehängt sind. Hoffentlich wechseln sie irgendwann zu WeakMaps . Das Bereinigen (oder sogar das Vorhandensein) des $ .cache scheint nicht offiziell dokumentiert zu sein.Verwenden Sie modernes Javascript mit
remove
!Dies ist eine neuere Methode zum Schreiben der Knotenentfernung in ES5. Es ist Vanilla JS und liest sich viel besser als frühere Versionen.
Die meisten Benutzer sollten über moderne Browser verfügen, oder Sie können bei Bedarf nach unten transpilieren.
Browser-Unterstützung - 95% Dezember 2019
quelle
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
Schleife. developer.mozilla.org/en-US/docs/Web/API/ParentNode/children developer.mozilla.org/en-US/docs/Web/API/Node/childNodeswhile (parent.firstChild && !parent.firstChild.remove());
[...parent.childNodes].forEach(el => el.remove());
while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); }
Wenn die Möglichkeit besteht, dass Nachkommen von jQuery betroffen sind, müssen Sie eine Methode verwenden, mit der jQuery-Daten bereinigt werden.
Die jQuery-
.empty()
Methode stellt sicher, dass alle Daten, die jQuery mit zu entfernenden Elementen verknüpft, bereinigt werden.Wenn Sie einfach
DOM
Methoden zum Entfernen der untergeordneten Elemente verwenden, bleiben diese Daten erhalten.quelle
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Wenn Sie jQuery verwenden:
Wenn Sie nicht:
quelle
Das schnellste...
Vielen Dank an Andrey Lushnikov für seinen Link zu jsperf.com (coole Seite!).
BEARBEITEN: Um klar zu sein, gibt es in Chrome keinen Leistungsunterschied zwischen firstChild und lastChild. Die Top-Antwort zeigt eine gute Lösung für die Leistung.
quelle
Wenn Sie den Knoten nur ohne seine untergeordneten Knoten haben möchten, können Sie auch eine Kopie davon erstellen:
Kommt darauf an, was du erreichen willst.
quelle
parent.replaceChild(cloned, original)
? Das ist möglicherweise schneller als das Entfernen von untergeordneten Elementen nacheinander und sollte für alles funktionieren, was das DOM unterstützt (also für alle Arten von XML-Dokumenten, einschließlich SVG). Das Festlegen von innerHTML ist möglicherweise auch schneller als das Entfernen von untergeordneten Elementen nacheinander. Dies funktioniert jedoch nur für HTML-Dokumente. Sollte das mal testen.addEventListener
.Hier ist ein anderer Ansatz:
quelle
Es ist wie innerText, außer Standard. Es ist etwas langsamer als
removeChild()
, aber es ist einfacher zu verwenden und macht keinen großen Leistungsunterschied, wenn Sie nicht zu viel Material zum Löschen haben.quelle
Als Antwort auf DanMan, Maarten und Matt. Das Klonen eines Knotens, um den Text festzulegen, ist in der Tat ein praktikabler Weg für meine Ergebnisse.
Dies funktioniert auch für Knoten, die sich nicht im Dom befinden und beim Versuch, auf den parentNode zuzugreifen, null zurückgeben. Wenn Sie sicher sein müssen, dass ein Knoten leer ist, bevor Sie Inhalte hinzufügen, ist dies sehr hilfreich. Betrachten Sie den Anwendungsfall darunter.
Ich finde diese Methode sehr nützlich, wenn Sie eine Zeichenfolge innerhalb eines Elements ersetzen. Wenn Sie nicht sicher sind, was der Knoten enthalten soll, anstatt sich Gedanken darüber zu machen, wie das Chaos beseitigt werden soll, beginnen Sie neu.
quelle
Folgendes mache ich normalerweise:
Und voila, später können Sie jedes dom-Element leeren mit:
quelle
domEl.innerHTML = ""
ist schlecht und gilt als schlechte PraxisDafür gibt es mehrere Möglichkeiten:
Das schnellste ():
Alternativen (langsamer):
Benchmark mit den vorgeschlagenen Optionen
quelle
Dadurch werden alle Knoten innerhalb des Elements entfernt.
quelle
innerText ist der Gewinner! http://jsperf.com/innerhtml-vs-removechild/133 . Bei allen vorherigen Tests wurde der innere Dom des übergeordneten Knotens bei der ersten Iteration gelöscht und dann innerHTML oder removeChild auf leeres div angewendet.
quelle
innerText
ist jedoch eine proprietäre MS-Sache. Ich sage nur.box
bin mir ziemlich sicher, dass dies ein fehlerhafter Test ist - er hängt davon ab, dass er nicht als Variable, sondern über die DOM-Suche basierend auf der ID verfügbar ist, und da diewhile
Schleife diesen langsamen Aufruf viele Male ausführt, wird er bestraft.Einfachste Möglichkeit, die untergeordneten Knoten eines Knotens über Javascript zu entfernen
quelle
Ich sah Leute tun:
dann sagte jemand, dass die Verwendung
el.lastNode
schneller istIch würde jedoch denken, dass dies das schnellste ist:
Was denken Sie?
ps: dieses thema hat mir das leben gerettet. Mein Firefox-Addon wurde abgelehnt, weil ich innerHTML verwendet habe. Es ist schon lange eine Gewohnheit. dann foudn ich das. und ich bemerkte tatsächlich einen Geschwindigkeitsunterschied. Beim Laden dauerte es eine Weile, bis der innerhtml aktualisiert wurde, jedoch wurde addElement sofort ausgeführt!
quelle
for (var i=0...
einen jedoch nicht ein. Aber hier ist, was ich bekam, als ich diese Tests durchführte: i.imgur.com/Mn61AmI.png In diesen drei Tests war firstNode schneller als lastNode und innerHTML, was wirklich cool istDie Verwendung einer Bereichsschleife fühlt sich für mich am natürlichsten an:
Nach meinen Messungen in Chrome und Firefox ist es ungefähr 1,3x langsamer. Unter normalen Umständen spielt dies möglicherweise keine Rolle.
quelle
quelle
Im Allgemeinen verwendet JavaScript Arrays, um Listen von DOM-Knoten zu referenzieren. Dies funktioniert also gut, wenn Sie Interesse daran haben, dies über das HTMLElements-Array zu tun. Erwähnenswert ist auch, dass ich in jedem Browser, einschließlich IE, funktionieren sollte, da ich anstelle von JavaScript-Proto eine Array-Referenz verwende.
quelle
Warum folgen wir hier nicht der einfachsten Methode?
quelle
Ich habe gerade gesehen, wie jemand diese Frage in einer anderen erwähnte und dachte, ich würde eine Methode hinzufügen, die ich noch nicht gesehen habe:
Die Löschfunktion nimmt das Element und verwendet den übergeordneten Knoten, um sich durch eine Kopie ohne untergeordnete Elemente zu ersetzen. Nicht viel Leistungsgewinn, wenn das Element dünn ist, aber wenn das Element eine Reihe von Knoten hat, werden die Leistungsgewinne realisiert.
quelle
Nur funktionaler Ansatz:
"childNodes" in domChildren gibt eine Knotenliste der unmittelbaren untergeordneten Elemente an, die leer ist, wenn keine gefunden werden. Um die Knotenliste zuzuordnen, konvertiert domChildren sie in ein Array. domEmpty ordnet eine Funktion domRemove allen Elementen zu, die sie entfernen.
Anwendungsbeispiel:
Entfernt alle Kinder aus dem Körperelement.
quelle
Andere Möglichkeiten in jQuery
quelle
.empty()
Methode,$("#foo").empty()
wäre einfach genugeinfach nur IE:
true
- bedeutet eine tiefe Entfernung - was bedeutet, dass auch alle Kinder entfernt werdenquelle
Der einfachste Weg:
quelle
container.innerHTML = null
, dass Internet Explorer den Text anzeigtnull
. Das entfernt die Kinder also nicht wirklich, würde ich sagen.einfach und schnell mit for loop !!
Dies wird nicht im
<span>
Tag funktionieren !quelle
<span>
TagWenn Sie etwas zurückbringen möchten
div
,innerHTML
ist das wahrscheinlich besser.Mein Beispiel:
Wenn ich die Methode
.firstChild
oder.lastChild
verwende,displayHTML()
funktioniert die Funktion danach nicht mehr, aber kein Problem mit der.innerHTML
Methode.quelle
Dies ist ein reines Javascript, das ich nicht mit jQuery verwende, aber es funktioniert in allen Browsern, auch im IE, und es ist sehr einfach zu verstehen
quelle
mit jQuery:
quelle
$('#foo').children().remove()
viel logischer