1168 votes

Supprimer tous les éléments enfants d'un nœud DOM en JavaScript ?

Comment faire pour supprimer tous les éléments enfants d'un nœud DOM en JavaScript ?

Disons que j'ai le HTML suivant (laid) :

<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 supprimer les enfants de foo de sorte que juste <p id="foo"></p> reste ?

Je pourrais juste le faire :

myNode.childNodes = new Array();

ou devrais-je utiliser une combinaison de removeElement ?

J'aimerais que la réponse soit directement DOM ; mais des points supplémentaires si vous fournissez également une réponse en jQuery avec la réponse DOM uniquement :)

2104voto

Gabriel McAdams Points 22323

Option 1 (beaucoup plus lente, 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);
}

6 votes

À partir de jQuery, on peut envisager ces deux questions : Cette méthode supprime non seulement les éléments enfants (et autres éléments descendants), mais aussi tout texte dans l'ensemble des éléments correspondants. En effet, selon la spécification DOM, toute chaîne de texte dans un élément est considérée comme un nœud enfant de cet élément. ET "Pour éviter les fuites de mémoire, jQuery supprime les autres constructions telles que les données et les gestionnaires d'événements des éléments enfants avant de supprimer les éléments eux-mêmes."

3 votes

@micha Je pense que votre test n'est pas bon. J'ai écrit le mien sur jsfidle ( jsfiddle.net/6K6mv/5 ) et voici le résultat. WHILE : 14ms ; INNERHTML : 7ms ; TEXTCONTENT : 7ms

3 votes

@m93a : en exécutant votre test plusieurs fois, j'obtiens des résultats qui varient de 6ms à 11ms. En fait, cela ne me dit rien. Les résultats sont plus proches les uns des autres que la variance en ms entre chaque testrun pour le même test. Pour mémoire : Ce n'est pas MON script, c'est jsperf.com. Regardez ceci pour mieux comprendre les résultats du test : stackoverflow.com/a/5262617/859877 y stackoverflow.com/questions/4986245/how-does-jsperf-work/

135voto

npjohns Points 21

La réponse actuellement acceptée est fausse en ce qui concerne innerHTML qui est plus lent (au moins dans IE et Chrome), comme m93a l'a correctement mentionné.

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

et

    node.innerHtml = ''

sont comparativement rapides (de 2 à 10 fois plus rapides que les autres méthodes selon mon benchmark), et innerHTML ne détruira pas vos gestionnaires d'événements et ne perturbera pas les références jquery. il est également recommandé comme solution ici : https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML

La méthode de manipulation du DOM la plus rapide (mais toujours plus lente que les deux précédentes) est la suppression des plages, mais celles-ci ne sont pas prises en charge avant IE9.

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

Les autres méthodes mentionnées semblent être comparables, mais beaucoup plus lentes que innerHTML, à l'exception de la méthode aberrante, jquery, qui est considérablement plus lente que tout le reste :

    $(node).contents().remove();

Les preuves sont ici :

http://jsperf.com/innerhtml-vs-removechild/167

Tous les liens jsperf que j'ai vérifiés dans cette réponse ne donnaient pas les résultats escomptés. Détails sur la page jsperf.

4 votes

Votre jsperf est complètement cassé. Ce n'est pas une très bonne preuve.

0 votes

Merci de l'avoir noté, je l'ai corrigé, la spécification insertBefore a changé et ne prend plus undefined pour le dernier paramètre.

4 votes

C'est actuellement la meilleure réponse. Tout le reste dans ce fil est de la désinformation ( !) Merci d'avoir nettoyé tous ces vieux et mauvais tests.

47voto

user113716 Points 143363
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 nettoie les données jQuery.

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

Le jQuery .empty() méthode garantira que toutes les données que jQuery a associées aux éléments supprimés seront nettoyées.

Si vous utilisez simplement DOM méthodes de suppression des enfants, ces données resteront.

0 votes

La méthode innerHTML est de loin la plus performante. Cela dit, les données sont nettoyées par la méthode .empty() de jquery : élimine les data() à l'intérieur de jquery associées aux balises enfant en utilisant une boucle récursive (lente, mais peut réduire l'utilisation de la mémoire de manière significative), évite les fuites de mémoire SI vous attachez des événements sans jquery, comme l'utilisation de .onclick=... . Si vous n'avez pas de tels événements dans les enfants à supprimer, alors le réglage de innerHTML ne fuira pas. La meilleure réponse est donc : cela dépend.

2 votes

Pourquoi ne pas simplement mettre l'expression firstChild directement dans la condition de la boucle while ? while ( myNode.firstChild ) {

0 votes

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

47voto

PleaseStand Points 16718

Si vous utilisez jQuery :

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

Si vous ne le faites pas :

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

24voto

Gabe Halsmer Points 303

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 !).

0 votes

Même chose sans l'avertissement LINT : clear : function ( container ) { for ( ; ; ) { var child = container.lastChild ; if ( !child ) break ; container.removeChild( child ) ; } }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X