Question Supprimer tous les éléments enfants d'un noeud DOM en JavaScript


Comment ferais-je pour supprimer tous les éléments enfants d'un noeud DOM en JavaScript?

Dites que j'ai le HTML suivant (moche):

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

Et je prends le noeud que je veux comme ça:

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

Comment pourrais-je enlever les enfants de foo pour que juste <p id="foo"></p> est laissé?

Pourrais-je juste faire:

myNode.childNodes = new Array();

ou devrais-je utiliser une combinaison de removeElement?

J'aimerais que la réponse soit directe DOM; si des points supplémentaires si vous fournissez également une réponse dans jQuery avec la réponse DOM seule.


571
2017-10-17 20:51


origine


Réponses:


Option 1 (beaucoup plus lent, voir les commentaires ci-dessous):

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

Option 2 (beaucoup plus rapide):

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

1141
2017-10-17 20:52



La réponse actuellement acceptée est fausse au sujet de innerHTML étant plus lent (au moins dans IE et Chrome), comme m93a correctement mentionné.

Chrome et FF sont considérablement plus rapides en utilisant cette méthode (qui détruira les données jquery attachées):

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

dans une seconde lointaine pour FF et Chrome, et le plus rapide dans IE:

node.innerHTML = '';

InnerHTML ne détruira pas vos gestionnaires d'événements et ne détruira pas les références jquery, c'est aussi recommandé comme solution ici: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML

La méthode de manipulation DOM la plus rapide (encore plus lente que les deux précédentes) est la suppression de Range, mais les plages ne sont pas supportées avant IE9.

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

Les autres méthodes mentionnées semblent être comparables, mais beaucoup plus lent que innerHTML, à l'exception de la valeur aberrante, jquery (1.1.1 et 3.1.1), qui est considérablement plus lent que toute autre chose:

$(node).empty();

Preuve ici:

http://jsperf.com/innerhtml-vs-removechild/167  http://jsperf.com/innerhtml-vs-removechild/300 https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript (Nouvel url pour redémarrer jsperf car l'édition de l'ancienne url ne fonctionne pas)

La "per-test-loop" de Jsperf est souvent interprétée comme "per-itération", et seule la première itération a des nœuds à supprimer pour que les résultats soient dénués de sens, au moment de la publication il y avait des tests incorrects.


79
2018-04-09 15:04



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

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

S'il y a une chance que vous ayez des descendants affectés par jQuery, alors vous doit utiliser une méthode qui nettoiera les données jQuery.

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

Le jQuery .empty() méthode veillera à ce que toutes les données que jQuery associé aux éléments en cours de suppression seront nettoyés.

Si vous utilisez simplement DOM méthodes d'enlèvement des enfants, ces données resteront.


38
2017-10-17 20:57



Si vous utilisez jQuery:

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

Si vous ne le faites pas:

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

30
2017-10-17 21:02



Le plus rapide...

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

Merci à Andrey Lushnikov pour son lien vers jsperf.com (site cool!).


14
2018-04-02 18:02



Utilisez le Javascript moderne, avec remove!

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

C'est une façon plus récente d'écrire la suppression des nœuds dans ES5. Il est vanillé JS et lit beaucoup plus agréable que les versions précédentes.

La plupart des utilisateurs devraient avoir des navigateurs modernes ou vous pouvez transpiler si nécessaire.

Support du navigateur - 91% avril 2018


12
2017-11-15 09:57



Si vous voulez seulement avoir le noeud sans ses enfants, vous pouvez aussi en faire une copie comme ceci:

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

Cela dépend de ce que vous essayez d'atteindre.


8
2017-10-17 21:13



element.textContent = '';

C'est comme innerText, sauf standard. Ses un peu plus lent que removeChild(), mais il est plus facile à utiliser et ne fera pas beaucoup de différence de performance si vous n'avez pas trop de choses à supprimer.


5
2018-03-28 17:13