¿Cómo haría para eliminar todos los elementos secundarios de un nodo DOM en JavaScript?
Digamos que tengo el siguiente (feo) HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
Y agarro el nodo que quiero así:
var myNode = document.getElementById("foo");
¿Cómo podría eliminar a los niños de foo
modo que solo <p id="foo"></p>
quede?
¿Podría simplemente hacer:
myNode.childNodes = new Array();
o debería usar alguna combinación de removeElement
?
Me gustaría que la respuesta fuera directamente DOM; aunque puntos adicionales si también proporciona una respuesta en jQuery junto con la respuesta solo DOM.
javascript
dom
Polaris878
fuente
fuente
innerHTML = ''
es más lento, pero no creo que esté "mal". Cualquier reclamo de pérdida de memoria debe ser respaldado con evidencia.La respuesta actualmente aceptada es incorrecta sobre
innerHTML
ser más lento (al menos en IE y Chrome), como se mencionó correctamente en m93a.Chrome y FF son mucho más rápidos con este método (que destruirá los datos jquery adjuntos):
en un distante segundo lugar para FF y Chrome, y más rápido en IE:
InnerHTML no destruirá sus controladores de eventos ni romperá las referencias de jquery , también se recomienda como solución aquí: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML .
El método de manipulación DOM más rápido (aún más lento que los dos anteriores) es la eliminación de Rango, pero los rangos no son compatibles hasta IE9.
Los otros métodos mencionados parecen ser comparables, pero mucho más lentos que innerHTML, excepto el atípico, jquery (1.1.1 y 3.1.1), que es considerablemente más lento que cualquier otra cosa:
Evidencia aquí:
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 (Nueva url para el reinicio de jsperf porque la edición de la antigua url no funciona)El "bucle de prueba" de Jsperf a menudo se entiende como "por iteración", y solo la primera iteración tiene nodos para eliminar, por lo que los resultados no tienen sentido, al momento de la publicación había pruebas en este hilo configuradas incorrectamente.
fuente
jQuery.cache
, causando una pérdida de memoria porque la única referencia disponible para administrar esos datos estaba en los elementos que acaba de destruir.cloneNode
apaga el contenedor, lo que significa que las referencias al contenedor no se mantienen (jquery o no). La memoria caché de Jquery puede hacer que valga la pena usar jquery para eliminar elementos si tiene datos jquery adjuntos. Esperemos que cambien a WeakMaps en algún momento. La limpieza (o incluso la existencia de) $ .cache no parece estar documentada oficialmente.Use Javascript moderno, con
remove
!Esta es una nueva forma de escribir la eliminación de nodos en ES5. Es vanilla JS y se lee mucho mejor que las versiones anteriores.
La mayoría de los usuarios deben tener navegadores modernos o puede transpilar si es necesario.
Soporte del navegador : 95% de diciembre de 2019
fuente
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
bucle. 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(); }
Si hay alguna posibilidad de que jQuery haya afectado a los descendientes, debe usar algún método que limpie los datos de jQuery.
El
.empty()
método jQuery asegurará que todos los datos que jQuery asocie con los elementos que se eliminen se limpiarán.Si simplemente usa
DOM
métodos para eliminar a los hijos, esos datos permanecerán.fuente
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Si usa jQuery:
Si no lo haces:
fuente
El más rápido...
Gracias a Andrey Lushnikov por su enlace a jsperf.com (¡sitio genial!).
EDITAR: para ser claros, no hay diferencia de rendimiento en Chrome entre firstChild y lastChild. La respuesta principal muestra una buena solución para el rendimiento.
fuente
Si solo desea tener el nodo sin sus hijos, también puede hacer una copia de esta manera:
Depende de lo que intentes lograr.
fuente
parent.replaceChild(cloned, original)
? Eso podría ser más rápido que eliminar a los niños uno por uno y debería funcionar en todo lo que sea compatible con el DOM (por lo tanto, cada tipo de documento XML, incluido SVG). Configurar innerHTML también puede ser más rápido que eliminar a los niños uno por uno, pero eso no funciona en nada más que en documentos HTML. Debería probar eso alguna vez.addEventListener
.Aquí hay otro enfoque:
fuente
Es como innerText, excepto estándar. Es un poco más lento que
removeChild()
, pero es más fácil de usar y no hará una gran diferencia en el rendimiento si no tiene demasiadas cosas para eliminar.fuente
En respuesta a DanMan, Maarten y Matt. Clonar un nodo para configurar el texto es, de hecho, una forma viable en mis resultados.
Además, esto funciona para los nodos que no están en el dom que devuelven nulo al intentar acceder al parentNode. Además, si necesita estar seguro, un nodo está vacío antes de agregar contenido, esto es realmente útil. Considere el caso de uso debajo.
Considero que este método es muy útil al reemplazar una cadena dentro de un elemento, si no está seguro de lo que contendrá el nodo, en lugar de preocuparse por cómo limpiar el desorden, comience de nuevo.
fuente
Esto es lo que suelo hacer:
Y listo, más tarde puedes vaciar cualquier elemento dom con:
fuente
domEl.innerHTML = ""
es pobre y se considera una mala prácticaHay un par de opciones para lograr eso:
El más rápido ():
Alternativas (más lentas):
Benchmark con las opciones sugeridas
fuente
Esto eliminará todos los nodos dentro del elemento.
fuente
innerText es el ganador! http://jsperf.com/innerhtml-vs-removechild/133 . En todas las pruebas anteriores, el dom interno del nodo primario se eliminó en la primera iteración y luego innerHTML o removeChild se aplicaron al div vacío.
fuente
innerText
Sin embargo, es una cosa propietaria de MS. Solo digo.box
estar disponible no como una variable sino a través de la búsqueda DOM basada en la identificación, y dado que elwhile
bucle hace esta llamada lenta muchas veces, se penaliza.La forma más sencilla de eliminar los nodos secundarios de un nodo a través de Javascript
fuente
vi gente haciendo:
entonces alguien dijo usando
el.lastNode
es más rápidoSin embargo, creo que este es el más rápido:
¿Qué piensas?
PD: este tema fue un salvavidas para mí. mi complemento de Firefox fue rechazado porque utilicé innerHTML. Ha sido un hábito durante mucho tiempo. entonces lo entiendo. y de hecho noté una diferencia de velocidad. al cargar el innerhtml tardó un tiempo en actualizarse, sin embargo, al agregar addElement es instantáneo.
fuente
for (var i=0...
uno. Pero esto es lo que obtuve cuando ejecuté esas pruebas: i.imgur.com/Mn61AmI.png, así que en esas tres pruebas firstNode fue más rápido que lastNode e innerHTML, lo cual es realmente genialUsar un bucle de rango me parece lo más natural:
Según mis mediciones en Chrome y Firefox, es aproximadamente 1.3 veces más lento. En circunstancias normales, esto quizás no importe.
fuente
fuente
En general, JavaScript utiliza matrices para hacer referencia a listas de nodos DOM. Entonces, esto funcionará bien si tiene interés en hacerlo a través de la matriz HTMLElements. Además, vale la pena señalar, porque estoy usando una referencia de matriz en lugar de protocolos de JavaScript, esto debería funcionar en cualquier navegador, incluido IE.
fuente
¿Por qué no estamos siguiendo el método más simple aquí "eliminar" en el interior mientras?
fuente
Acabo de ver a alguien mencionar esta pregunta en otra y pensé que agregaría un método que aún no vi:
La función clear es tomar el elemento y usar el nodo padre para reemplazarse con una copia sin sus hijos. No se gana mucho rendimiento si el elemento es escaso, pero cuando el elemento tiene un grupo de nodos, se obtienen ganancias de rendimiento.
fuente
Enfoque funcional único:
"childNodes" en domChildren dará una lista de nodos de los elementos secundarios inmediatos, que está vacía cuando no se encuentra ninguno. Para mapear sobre la lista de nodos, domChildren la convierte en matriz. domEmpty asigna una función domRemove sobre todos los elementos que la eliminan.
Ejemplo de uso:
elimina a todos los niños del elemento del cuerpo.
fuente
Otras formas en jQuery
fuente
.empty()
método, solo$("#foo").empty()
sería suficientesimplemente solo IE:
true
- significa hacer una extracción profunda - lo que significa que también se eliminan todos los niñosfuente
La forma más fácil:
fuente
container.innerHTML = null
Internet Explorer muestre el textonull
. Entonces, esto realmente no elimina a los niños, diría.simple y rápido usando for loop !!
¡Esto no funcionará en la
<span>
etiqueta!fuente
<span>
etiquetaSi quieres volver a poner algo en eso
div
,innerHTML
probablemente sea mejor.Mi ejemplo:
Si uso el método
.firstChild
o.lastChild
ladisplayHTML()
función no funciona después, pero no hay problema con el.innerHTML
método.fuente
Este es un javascript puro, no estoy usando jQuery, pero funciona en todos los navegadores, incluso en IE, y es muy fácil de entender
fuente
con jQuery:
fuente
$('#foo').children().remove()
mucho más lógico