Odeberte všechny podřízené prvky uzlu DOM v JavaScriptu

Jak bych postupoval při odstraňování všech podřízených prvků uzlu DOM v JavaScriptu?

Řekněme, že mám následující (ošklivý) HTML:

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

A chytnu uzel, který chci, takto:

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

Jak mohu odstranit potomky foo takže stačí <p id="foo"></p> zbývá?

Mohl bych udělat:

myNode.childNodes = new Array();

nebo bych měl používat nějakou kombinaci removeElement ?

Chtěl bych, aby odpověď byla přímo DOM; i když body navíc, pokud spolu s odpovědí pouze DOM poskytnete odpověď v jQuery.

Odpověď

Možnost 1 A:Vymazání innerHTML .

  • Tento přístup je jednoduchý, ale nemusí být vhodný pro vysoce výkonné aplikace, protože spouští analyzátor HTML prohlížeče (ačkoli prohlížeče mohou optimalizovat pro případ, kdy je hodnotou prázdný řetězec).

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  myNode.innerHTML = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello</span>
</div>
<button id='doFoo'>Remove via innerHTML</button>

Možnost 1 B:Vymazání textContent

  • Jako výše, ale použijte .textContent . Podle MDN to bude rychlejší než innerHTML protože prohlížeče nebudou vyvolávat své analyzátory HTML a místo toho okamžitě nahradí všechny potomky prvku jediným #text uzel.

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  myNode.textContent = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello</span>
</div>
<button id='doFoo'>Remove via textContent</button>

Možnost 2 A:Smyčka pro odstranění každých lastChild :

  • Dřívější úprava této odpovědi používala firstChild , ale toto je aktualizováno na použití lastChild jako v informatice obecně , je výrazně rychlejší odstranit poslední prvek kolekce než k odstranění prvního prvku (v závislosti na tom, jak je kolekce implementována).
  • Smyčka pokračuje v kontrole firstChild pro jistotu je rychlejší zkontrolovat firstChild než lastChild (např. pokud je seznam prvků implementován jako řízený propojený seznam UA).

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  while (myNode.firstChild) {
    myNode.removeChild(myNode.lastChild);
  }
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello</span>
</div>
<button id='doFoo'>Remove via lastChild-loop</button>

Možnost 2 B:Smyčka pro odstranění každých lastElementChild :

  • Tento přístup zachovává vše, co není Element (konkrétně #text uzly a <!-- comments --> ) potomci rodiče (ale ne jejich potomci) – a to může být ve vaší aplikaci žádoucí (např. některé šablonovací systémy, které k ukládání pokynů šablony používají vložené komentáře HTML).
  • Tento přístup se až do posledních let nepoužíval, protože Internet Explorer přidal pouze podporu pro lastElementChild v IE9.

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  while (myNode.lastElementChild) {
    myNode.removeChild(myNode.lastElementChild);
  }
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <!-- This comment won't be removed -->
  <span>Hello <!-- This comment WILL be removed --></span>
  <!-- But this one won't. -->
</div>
<button id='doFoo'>Remove via lastElementChild-loop</button>

Bonus:Element.clearChildren opičí náplast:

  • Do Element můžeme přidat novou vlastnost metody prototyp v JavaScriptu, aby se zjednodušilo jeho vyvolání na pouhých el.clearChildren() (kde el je jakýkoli Objekt prvku HTML).
  • (Přísně vzato se jedná o opičí záplatu, nikoli polyfill, protože se nejedná o standardní funkci DOM nebo chybějící funkci. Všimněte si, že opičí záplatování se v mnoha situacích oprávněně nedoporučuje.)

if( typeof Element.prototype.clearChildren === 'undefined' ) {
    Object.defineProperty(Element.prototype, 'clearChildren', {
      configurable: true,
      enumerable: false,
      value: function() {
        while(this.firstChild) this.removeChild(this.lastChild);
      }
    });
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello <!-- This comment WILL be removed --></span>
</div>
<button onclick="this.previousElementSibling.clearChildren()">Remove via monkey-patch</button>