it-swarm.com.de

Entfernen Sie alle untergeordneten Elemente eines DOM-Knotens in JavaScript

Wie entferne ich alle untergeordneten Elemente eines DOM-Knotens in JavaScript?

Angenommen, ich habe folgendes (hässliches) HTML:

<p id="foo">
    <span>hello</span>
    <div>world</div>
</p>

Und ich schnappe mir den gewünschten Knoten so:

var myNode = document.getElementById("foo");

Wie könnte ich die Kinder von foo entfernen, so dass nur noch <p id="foo"></p> übrig bleibt?

Könnte ich nur tun:

myNode.childNodes = new Array();

oder sollte ich eine Kombination von removeElement verwenden?

Ich möchte, dass die Antwort direkt im DOM steht. Allerdings, wenn Sie zusätzlich in jQuery eine Antwort zusammen mit der DOM-only-Antwort angeben.

656
Polaris878

Option 1 (viel langsamer, siehe Kommentare unten):

var myNode = document.getElementById("foo");
myNode.innerHTML = '';

Option 2 (viel schneller):

var myNode = document.getElementById("foo");
while (myNode.firstChild) {
    myNode.removeChild(myNode.firstChild);
}
1315
Gabriel McAdams

Die derzeit akzeptierte Antwort ist falsch, da innerHTML langsamer ist (zumindest in IE und Chrome), wie m93a richtig erwähnt.

Chrome und FF sind mit dieser Methode erheblich schneller (wodurch angehängte Jquery-Daten zerstört werden):

var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode ,node);

in einer fernen Sekunde für FF und Chrome und im IE am schnellsten:

node.innerHTML = '';

InnerHTML zerstört nicht Ihre Event-Handler oder bricht Jquery-Referenzen, es wird hier auch als Lösung 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 des Bereichs, aber Bereiche werden nicht bis zum IE9 unterstützt.

var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();

Die anderen genannten Methoden scheinen vergleichbar zu sein, sind jedoch viel langsamer als innerHTML, mit Ausnahme des Ausreißers jquery (1.1.1 und 3.1.1), das wesentlich langsamer ist als alles andere:

$(node).empty();

Beweis hier:

http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300 https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript (Neue URL für jsperf-Neustart, da die alte URL 'isn' bearbeitet wird. t arbeiten)

Die "Pro-Test-Schleife" von Jsperf wird oft als "Pro-Iteration" verstanden, und nur die erste Iteration hat Knoten, die entfernt werden müssen, so dass die Ergebnisse bedeutungslos sind. Zum Zeitpunkt der Veröffentlichung gab es Tests in diesem Thread, die falsch eingerichtet wurden.

84
npjohns
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;

while( fc ) {
    myNode.removeChild( fc );
    fc = myNode.firstChild;
}

Wenn die Möglichkeit besteht, dass Sie von jQuery abhängige Nachkommen haben, verwenden Sie must eine Methode, die die jQuery-Daten bereinigt.

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

Die jQuery .empty()-Methode stellt sicher, dass alle Daten, die jQuery den zu entfernenden Elementen zugeordnet hat, bereinigt werden.

Wenn Sie einfach die DOM-Methoden zum Entfernen der untergeordneten Elemente verwenden, bleiben diese Daten erhalten.

40
user113716

Wenn Sie jQuery verwenden:

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

Wenn du es nicht tust:

var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);
33
PleaseStand

Verwenden Sie modernes Javascript mit remove!

const parent = document.getElementById("foo");
while (parent.firstChild) {
    parent.firstChild.remove();
}

Dies ist eine neuere Methode zum Schreiben von Knoten in ES5. Es ist Vanilla JS und liest viel schöner als frühere Versionen.

Die meisten Benutzer sollten über moderne Browser verfügen, oder Sie können sich bei Bedarf nach unten bewegen.

Browserunterstützung - 91% April 2018

25
Gibolt

Das schnellste...

var removeChilds = function (node) {
    var last;
    while (last = node.lastChild) node.removeChild(last);
};

Danke an Andrey Lushnikov für sein Link zu jsperf.com (coole Seite!).

BEARBEITEN: Um klar zu sein, gibt es in Chrome keinen Leistungsunterschied zwischen firstChild und lastChild. Die oberste Antwort zeigt eine gute Lösung für die Leistung.

18
Gabe Halsmer

Wenn Sie den Knoten nur ohne seine Kinder haben möchten, können Sie auch eine Kopie davon wie folgt erstellen:

var dupNode = document.getElementById("foo").cloneNode(false);

Hängt davon ab, was Sie erreichen wollen.

9
DanMan

Hier ist ein anderer Ansatz:

function removeAllChildren(theParent){

    // Create the Range object
    var rangeObj = new Range();

    // Select all of theParent's children
    rangeObj.selectNodeContents(theParent);

    // Delete everything that is selected
    rangeObj.deleteContents();
}
5
Nathan K
element.textContent = '';

Es ist wie innerer Text, außer Standard. Es ist etwas langsamer als removeChild(), aber es ist einfacher zu bedienen und macht keinen großen Leistungsunterschied, wenn Sie nicht zu viel Material zum Löschen haben.

5
bjb568

Als Antwort auf DanMan, Maarten und Matt. Das Klonen eines Knotens, um den Text festzulegen, ist in meinen Ergebnissen tatsächlich ein gangbarer Weg.

// @param {node} node
// @return {node} empty node
function removeAllChildrenFromNode (node) {
  var Shell;
  // do not copy the contents
  Shell = node.cloneNode(false);

  if (node.parentNode) {
    node.parentNode.replaceChild(Shell, node);
  }

  return Shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = removeAllChildrenFromNode( myNode );

Dies funktioniert auch für Knoten außerhalb des Doms, die beim Versuch, auf den ParentNode zuzugreifen, NULL zurückgeben. Wenn Sie sicher sein müssen, dass ein Knoten vor dem Hinzufügen von Inhalten leer ist, ist dies sehr hilfreich. Betrachten Sie den Anwendungsfall darunter.

// @param {node} node
// @param {string|html} content
// @return {node} node with content only
function refreshContent (node, content) {
  var Shell;
  // do not copy the contents
  Shell = node.cloneNode(false);

  // use innerHTML or you preffered method
  // depending on what you need
  Shell.innerHTML( content );

  if (node.parentNode) {
    node.parentNode.replaceChild(Shell, node);
  }

  return Shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = refreshContent( myNode );

Ich finde diese Methode sehr nützlich, wenn Sie eine Zeichenfolge in einem Element ersetzen, wenn Sie nicht sicher sind, was der Knoten enthalten wird.

4
jeroen

Es gibt mehrere Möglichkeiten, dies zu erreichen:

Das schnellste ():

while (node.lastChild) {
  node.removeChild(node.lastChild);
}

Alternativen (langsamer):

while (node.firstChild) {
  node.removeChild(node.firstChild);
}

while (node.hasChildNodes()) {
  node.removeChild(node.lastChild);
}

Benchmark mit den vorgeschlagenen Optionen

3
magiccrafter

ich sah Leute tun:

while (el.firstNode) {
    el.removeChild(el.firstNode);
}

dann sagte jemand, el.lastNode sei schneller

ich würde jedoch denken, dass dies das schnellste ist:

var children = el.childNodes;
for (var i=children.length - 1; i>-1; i--) {
    el.removeNode(children[i]);
}

was denkst du?

ps: dieses thema war für mich ein lebensretter. mein Firefox-Addon wurde abgelehnt, da ich innerHTML verwendete. Es ist seit langem eine Gewohnheit. dann habe ich das gefälscht. und ich habe tatsächlich einen Geschwindigkeitsunterschied bemerkt. Beim Laden hat das innerehtml eine Weile gedauert, um ein Update durchzuführen.

3
Noitidart
var empty_element = function (element) {

    var node = element;

    while (element.hasChildNodes()) {              // selected elem has children

        if (node.hasChildNodes()) {                // current node has children
            node = node.lastChild;                 // set current node to child
        }
        else {                                     // last child found
            console.log(node.nodeName);
            node = node.parentNode;                // set node to parent
            node.removeChild(node.lastChild);      // remove last node
        }
    }
}

Dadurch werden alle Knoten innerhalb des Elements entfernt.

3
Henrik

Einfachste Möglichkeit, die untergeordneten Knoten eines Knotens über Javascript zu entfernen

var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
   myNode.removeChild(myNode.lastChild);
}
2
Chaitanya Bapat

innerText ist der Gewinner! http://jsperf.com/innerhtml-vs-removechild/133 . Bei allen vorherigen Tests wurden der innere dom des übergeordneten Knotens bei der ersten Iteration gelöscht und dann innerHTML oder removeChild auf leeres div angewendet.

2
Alexey

Die Verwendung einer Entfernungsschleife fühlt sich für mich am natürlichsten an:

for (var child of node.childNodes) {
    child.remove();
}

Nach meinen Messungen in Chrome und Firefox ist es etwa 1,3x langsamer. Unter normalen Umständen wird dies vielleicht keine Rolle spielen.

2
emu

Folgendes mache ich normalerweise:

HTMLElement.prototype.empty = function() {
    while (this.firstChild) {
        this.removeChild(this.firstChild);
    }
}

Und voila, später können Sie jedes dom-Element mit leeren:

anyDom.empty()
1
Ado Ren

Im Allgemeinen verwendet JavaScript Arrays, um auf Listen von DOM-Knoten zu verweisen. Dies funktioniert also gut, wenn Sie daran interessiert sind, das Array HTMLElements zu verwenden. Es ist auch erwähnenswert, da ich eine Arrayreferenz anstelle von JavaScript-Protos verwende, dies sollte in jedem Browser funktionieren, einschließlich IE.

while(nodeArray.length !== 0) {
  nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
1
r00t hkr

Ich habe gerade gesehen, dass jemand diese Frage in einer anderen erwähnt hat und dachte, ich würde eine Methode hinzufügen, die ich noch nicht gesehen habe:

function clear(el) {
    el.parentNode.replaceChild(el.cloneNode(false), el);
}

var myNode = document.getElementById("foo");
clear(myNode);

Die Löschfunktion übernimmt 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.

0

Warum folgen wir nicht der einfachsten Methode, die hier innerhalb von Loops "entfernt" wird.

const foo = document.querySelector(".foo");
while (foo.firstChild) {
  foo.firstChild.remove();     
}
  • Auswahl des übergeordneten div
  • Verwenden der "remove" -Methode in einer While-Schleife zum Entfernen des ersten untergeordneten Elements, bis es keine mehr gibt.
0
NEelansh VErma