Comment pourrais-je supprimer tous les éléments enfants d'un nœud DOM en JavaScript?
Disons que j'ai le HTML (moche) suivant:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
Et j'attrape le nœud que je veux comme ça:
var myNode = document.getElementById("foo");
Comment pourrais-je retirer les enfants de foo
sorte qu'il ne <p id="foo"></p>
reste que?
Puis-je simplement 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 dans jQuery avec la réponse DOM uniquement.
javascript
dom
Polaris878
la source
la source
innerHTML = ''
est plus lent, mais je ne pense pas que ce soit "mal". Toute allégation de fuite de mémoire doit être accompagnée de preuves.La réponse actuellement acceptée est erronée d'
innerHTML
être plus lent (au moins dans IE et Chrome), comme m93a l'a correctement mentionné.Chrome et FF sont considérablement plus rapides à l'aide de cette méthode (qui détruira les données jquery jointes):
dans une seconde éloignée pour FF et Chrome, et le plus rapide dans IE:
InnerHTML ne détruira pas vos gestionnaires d'événements ou ne cassera 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 DOM la plus rapide (toujours plus lente que les deux précédentes) est la suppression de la plage, mais les plages ne sont pas prises en charge avant IE9.
Les autres méthodes mentionnées semblent comparables, mais beaucoup plus lentes que innerHTML, à l'exception de la valeur aberrante, jquery (1.1.1 et 3.1.1), qui est considérablement plus lente que toute autre chose:
Preuve ici:
http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300https://jsperf.com/remove-all-child-elements-of-a- dom-node-in-javascript (Nouvelle URL pour le redémarrage de jsperf car la modification de l'ancienne URL ne fonctionne pas)La «boucle par test» de Jsperf est souvent comprise comme «par itération», et seule la première itération a des nœuds à supprimer, donc les résultats n'ont aucun sens, au moment de la publication, il y avait des tests dans ce thread mal configurés.
la source
jQuery.cache
perte de données , provoquant une fuite de mémoire car la seule référence disponible pour gérer ces données se trouvait sur les éléments que vous venez de détruire.cloneNode
désactive le conteneur, ce qui signifie que les références au conteneur ne sont pas conservées (jquery ou autre). Le cache de Jquery peut valoir la peine d'utiliser jquery pour supprimer des éléments si des données jquery y sont attachées. Espérons qu'ils passeront à WeakMaps à un moment donné. Le nettoyage (ou même l'existence de) $ .cache ne semble pas être officiellement documenté.Utilisez Javascript moderne, avec
remove
!Il s'agit d'une nouvelle façon d'écrire la suppression de nœuds dans ES5. Il est vanilla JS et se lit beaucoup mieux que les versions précédentes.
La plupart des utilisateurs devraient avoir des navigateurs modernes ou vous pouvez les transpiler si nécessaire.
Prise en charge du navigateur - 95% déc.2019
la source
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
boucle. developer.mozilla.org/en-US/docs/Web/API/ParentNode/children developer.mozilla.org/en-US/docs/Web/API/Node/childNodeswhile (parent.firstChild && !parent.firstChild.remove());
[...parent.childNodes].forEach(el => el.remove());
while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); }
S'il y a une chance que vous ayez des descendants affectés par jQuery, vous devez utiliser une méthode qui nettoiera les données jQuery.
La
.empty()
méthode jQuery garantira que toutes les données que jQuery associées aux éléments supprimés seront nettoyées.Si vous utilisez simplement des
DOM
méthodes de suppression des enfants, ces données resteront.la source
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Si vous utilisez jQuery:
Si vous ne le faites pas:
la source
Le plus rapide...
Merci à Andrey Lushnikov pour son lien vers jsperf.com (site sympa!).
EDIT: pour être clair, il n'y a pas de différence de performances dans Chrome entre firstChild et lastChild. La première réponse montre une bonne solution pour les performances.
la source
Si vous souhaitez uniquement avoir le nœud sans ses enfants, vous pouvez également en faire une copie comme ceci:
Cela dépend de ce que vous essayez de réaliser.
la source
parent.replaceChild(cloned, original)
? Cela pourrait être plus rapide que de supprimer les enfants un par un et devrait fonctionner sur tout ce qui prend en charge le DOM (donc tous les types de documents XML, y compris SVG). La définition de innerHTML peut également être plus rapide que la suppression des enfants un par un, mais cela ne fonctionne que sur des documents HTML. Devrait tester cela un certain temps.addEventListener
.Voici une autre approche:
la source
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.la source
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.
Cela fonctionne également pour les nœuds qui ne se trouvent pas dans le dom et qui renvoient null lorsqu'ils tentent d'accéder au parentNode. De plus, si vous devez être sûr qu'un nœud est vide avant d'ajouter du contenu, cela est vraiment utile. Considérez le cas d'utilisation ci-dessous.
Je trouve cette méthode très utile lors du remplacement d'une chaîne à l'intérieur d'un élément, si vous n'êtes pas sûr de ce que le nœud contiendra, au lieu de vous inquiéter comment nettoyer le gâchis, recommencez à zéro.
la source
Voici ce que je fais habituellement:
Et voila, plus tard, vous pouvez vider n'importe quel élément dom avec:
la source
domEl.innerHTML = ""
mauvaise et considérée comme une mauvaise pratiqueIl existe deux options pour y parvenir:
Le plus rapide ():
Alternatives (plus lentes):
Benchmark avec les options suggérées
la source
Cela supprimera tous les nœuds de l'élément.
la source
innerText est le gagnant! http://jsperf.com/innerhtml-vs-removechild/133 . Lors de tous les tests précédents, le dom interne du nœud parent a été supprimé lors de la première itération, puis innerHTML ou removeChild lorsqu'il était appliqué à div vide.
la source
innerText
est une chose MS propriétaire cependant. Je dis juste.box
disponibilité non pas en tant que var mais via la recherche DOM basée sur id, et puisque lawhile
boucle effectue cet appel lent plusieurs fois, il est pénalisé.Moyen le plus simple de supprimer les nœuds enfants d'un nœud via Javascript
la source
j'ai vu des gens faire:
alors quelqu'un a dit que l'utilisation
el.lastNode
est plus rapidemais je pense que c'est le plus rapide:
Qu'est-ce que tu penses?
ps: ce sujet m'a sauvé la vie. mon addon firefox a été rejeté car j'ai utilisé innerHTML. C'est une habitude depuis longtemps. alors je trouve ça. et j'ai remarqué une différence de vitesse. lors du chargement, le innerhtml a mis un certain temps à se mettre à jour, mais en passant par addElement son instant!
la source
for (var i=0...
celui cependant. Mais voici ce que j'ai obtenu lorsque j'ai exécuté ces tests: i.imgur.com/Mn61AmI.png donc dans ces trois tests, firstNode était plus rapide que lastNode et innerHTML, ce qui est vraiment coolL'utilisation d'une boucle de plage me semble la plus naturelle:
Selon mes mesures dans Chrome et Firefox, il est environ 1,3 fois plus lent. Dans des circonstances normales, cela n'aura peut-être pas d'importance.
la source
la source
En règle générale, JavaScript utilise des tableaux pour référencer les listes de nœuds DOM. Donc, cela fonctionnera bien si vous avez un intérêt à le faire via le tableau HTMLElements. En outre, il convient de noter, car j'utilise une référence de tableau au lieu de proto JavaScript, cela devrait fonctionner dans n'importe quel navigateur, y compris IE.
la source
Pourquoi ne suivons-nous pas la méthode la plus simple ici "supprimer" en boucle à l'intérieur de while.
la source
Je viens de voir quelqu'un mentionner cette question dans une autre et j'ai pensé ajouter une méthode que je ne voyais pas encore:
La fonction clear prend l'élément et utilise le nœud parent pour se remplacer par une copie sans ses enfants. Pas beaucoup de gain de performances si l'élément est clairsemé mais lorsque l'élément a un tas de nœuds, les gains de performances sont réalisés.
la source
Approche fonctionnelle uniquement:
"childNodes" dans domChildren donnera une nodeList des éléments enfants immédiats, qui est vide quand aucun n'est trouvé. Afin de mapper sur la nodeList, domChildren le convertit en tableau. domEmpty mappe une fonction domRemove sur tous les éléments qui la supprime.
Exemple d'utilisation:
supprime tous les enfants de l'élément corps.
la source
Autres façons dans jQuery
la source
.empty()
méthode,$("#foo").empty()
serait tout simplement suffisantsimplement IE:
true
- signifie faire un retrait profond - ce qui signifie que tous les enfants sont également retirésla source
La façon la plus simple:
la source
container.innerHTML = null
que Internet Explorer affiche le textenull
. Donc, cela n'enlève pas vraiment les enfants, je dirais.utilisation simple et rapide de la boucle !!
cela ne fonctionnera pas dans la
<span>
balise!la source
<span>
baliseSi vous voulez y remettre quelque chose
div
,innerHTML
c'est probablement mieux.Mon exemple:
Si j'utilise la méthode
.firstChild
ou.lastChild
ladisplayHTML()
fonction ne fonctionne pas par la suite, mais aucun problème avec la.innerHTML
méthode.la source
Ceci est un pur javascript je n'utilise pas jQuery mais fonctionne dans tous les navigateurs même IE et il est très simple à comprendre
la source
avec jQuery:
la source
$('#foo').children().remove()
beaucoup plus logique