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

Comment puis-je supprimer la suppression de tous les éléments enfants d'un noeud DOM en JavaScript?

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

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

Et je prends le noeud que je veux:

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

Comment puis-je supprimer les enfants de foo sorte que juste <p id="foo"></p> soit laissé?

Je pourrais simplement faire:

 myNode.childNodes = new Array(); 

Ou devrais-je utiliser une combinaison de removeElement ?

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

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

La réponse actuellement acceptée est incorrecte: innerHTML étant plus lent (au moins dans IE et Chrome), comme l'a mentionné correctement m93a.

Chrome et FF sont nettement 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 distante pour FF et Chrome, et plus rapide dans IE:

 node.innerHTML = ''; 

InnerHTML ne détruit pas vos gestionnaires d'événements ou ne casse pas les références jquery , il est également recommandé en tant que 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édents) est l'élimination de la plage, mais les plages ne sont pas prises en charge jusqu'à 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 l'outlier, jquery (1.1.1 et 3.1.1), qui est considérablement plus lent que toute autre chose:

 $(node).empty(); 

Des preuves 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 (Nouvelle URL pour le redémarrage jsperf car l'édition de l'ancienne URL ne fonctionne pas)

La boucle "per-test-loop" de Jsperf est souvent comprise comme "per-itération", et seule la première itération a des noeuds à éliminer afin que les résultats n'aient pas de sens, au moment de l'affichage, des tests dans ce thread étaient incorrects.

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

Si vous avez des descendants affectés par jQuery, vous devez utiliser une méthode qui va nettoyer les données jQuery.

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

La .empty() jQuery .empty() garantira que toutes les données jQuery associées aux éléments en cours de suppression seront nettoyées.

Si vous utilisez simplement des méthodes DOM pour enlever les enfants, ces données resteront.

Si vous utilisez jQuery:

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

Si vous ne le faites pas:

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

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 (cool site!).

Si vous voulez seulement avoir le nœud sans ses enfants, vous pouvez également en faire une copie comme ceci:

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

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

 element.textContent = ''; 

C'est comme innerText, sauf standard. C'est 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.

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

Il s'agit d'une méthode plus récente pour écrire l'élimination des noeuds dans ES5. C'est vanilla JS et lit beaucoup plus cher que les versions précédentes.

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

 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 } }} 

Cela éliminera tous les noeuds de l'élément.

Voici une autre approche:

 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(); } 

InnerText est le gagnant! http://jsperf.com/innerhtml-vs-removechild/133 . Dans tous les tests précédents, le dom intérieur du nœud parent a été supprimé à la première itération et ensuite innerHTML ou removeChild lorsqu'il a été appliqué à la division vide.

Le moyen le plus simple de supprimer les nœuds enfants d'un nœud via Javascript

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

Il y a quelques options pour y parvenir:

Le plus rapide ():

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

Alternatives (plus lentement):

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

Indice de référence avec les options proposées

J'ai vu des gens:

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

Alors quelqu'un a dit utiliser el.lastNode est plus rapide

Cependant, je pense que c'est le plus rapide:

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

Qu'est-ce que tu penses?

Ps: ce sujet était un économiseur de vie pour moi. Mon addon firefox a été rejeté parce que j'ai utilisé innerHTML. C'est une habitude depuis longtemps. Alors je dirais ça. Et j'ai remarqué une différence de vitesse. Sur le chargement du innerhtml a pris un certain temps pour la mise à jour, mais va par addElement son instantané!

En réponse à DanMan, Maarten et Matt. Le clonage d'un nœud, pour définir le texte est en effet un moyen viable dans mes résultats.

 // @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 ); 

Cela fonctionne également pour les nœuds non dans le dom qui renvoient lorsque vous essayez d'accéder à parentNode. En outre, si vous devez être en sécurité, un nœud est vide avant d'ajouter du contenu, cela est vraiment utile. Considérons le cas d'utilisation en dessous.

 // @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 ); 

Je trouve cette méthode très utile lors du remplacement d'une chaîne à l'intérieur d'un élément, si vous ne savez pas ce que le noeud contiendra, au lieu de vous inquiéter de la façon de nettoyer le désordre, commencer à nouveau.

C'est un javascript pur, je n'utilise pas jQuery mais fonctionne dans tous les navigateurs même IE

 <div id="my_div"> <p>i am the first child</p> <p>i am another paragraphs</p> <p>enven me also i am another paragraphs</p> </div> <button id ="my_button>Remove nodes ?</button> document.getElementById("my_button").addEventListener("click",function(){ let parent_node =document.getElemetById("my_div"); let last_child =parent_node.lastChild; while(last_child){ parent_node.removeChild(last_child); } }) 

Ou vous pouvez simpli faire cela

 document.getElementById("my_button").addEventListener("click",function(){ let parent_node =document.getElemetById("my_div"); parent_node.innerHTML =""; }) 

Généralement, JavaScript utilise des tableaux pour référencer les listes de noeuds DOM. Donc, cela fonctionnera bien si vous avez intérêt à le faire via le tableau HTMLElements. Aussi, il convient de noter, car j'utilise une référence de tableau au lieu de JavaScript proto, cela devrait fonctionner dans n'importe quel navigateur, y compris IE.

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

Autres façons de jQuery

 var foo = $("#foo"); foo.children().remove(); or $("*", foo ).remove(); or foo.html(""); 

Dans jQuery, vous venez d'utiliser ceci:

 $("#target").empty(); 

Code d'exemple:

 $("#button").click(function(){ $("#target").empty(); }); 

Simplement IE:

 parentElement.removeNode(true); 

true – signifie faire un retrait profond – ce qui signifie que tous les enfants sont également enlevés

Option 2 de la réponse gagnante .

 function emptyElement(element) { var myNode = element; while (myNode.firstChild) { myNode.removeChild(myNode.firstChild); } } emptyElement(document.body) 

Avec jQuery:

 $("#foo").find("*").remove();