Pregunta Eliminar todos los elementos secundarios de un nodo DOM en JavaScript


¿Cómo podría 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 hijos de foo para que solo <p id="foo"></p> ¿es izquierda?

¿Podría hacerlo?

myNode.childNodes = new Array();

o debería estar usando alguna combinación de removeElement?

Me gustaría que la respuesta fuera DOM directa; aunque puntos extra si también proporciona una respuesta en jQuery junto con la respuesta DOM-only.


571
2017-10-17 20:51


origen


Respuestas:


Opción 1 (mucho más lento, ver comentarios a continuación):

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

Opción 2 (mucho más rápido):

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

1141
2017-10-17 20:52



La respuesta actualmente aceptada es incorrecta acerca de que innerHTML es 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 adjuntos de jquery):

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

en un segundo distante para FF y Chrome, y más rápido en IE:

node.innerHTML = '';

InnerHTML no destruirá sus controladores de eventos ni romperá las referencias de jquery, también se recomienda como una 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 del rango, pero los rangos no son compatibles hasta IE9.

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

Los otros métodos mencionados parecen ser comparables, pero mucho más lentos que innerHTML, a excepción del valor atípico, jquery (1.1.1 y 3.1.1), que es considerablemente más lento que cualquier otra cosa:

$(node).empty();

Evidencia aquí:

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 (Nueva URL para jsperf reiniciar porque la edición de la antigua url no funciona)

El "bucle de prueba" de Jsperf a menudo se entiende como "iteración", y solo la primera iteración tiene nodos para eliminar, por lo que los resultados no tienen sentido, en el momento de la publicación, las pruebas en este hilo se configuraron incorrectamente.


79
2018-04-09 15:04



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

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

Si hay alguna posibilidad de que tenga jQuery descendientes afectados, entonces usted debe use algún método que borre los datos de jQuery.

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

El jQuery .empty() método garantizará que todos los datos que jQuery haya asociado a los elementos que se eliminen se eliminarán.

Si simplemente usa DOM métodos de eliminación de los niños, esa información se mantendrá.


38
2017-10-17 20:57



Si usas jQuery:

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

Si no lo haces:

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

30
2017-10-17 21:02



El más rápido...

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

Gracias a Andrey Lushnikov por su enlace a jsperf.com (sitio genial!).


14
2018-04-02 18:02



Use Javascript moderno, con remove!

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

Esta es una forma más nueva de escribir la eliminación de nodos en ES5. Es vainilla JS y lee mucho mejor que las versiones anteriores.

La mayoría de los usuarios debe tener navegadores modernos o puede transportarlos si es necesario.

Soporte del navegador - 91% abr 2018


12
2017-11-15 09:57



Si solo desea tener el nodo sin sus hijos, también puede hacer una copia de este modo:

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

Depende de lo que estás tratando de lograr.


8
2017-10-17 21:13