remove - Eliminar todos los elementos secundarios de un nodo DOM en JavaScript
removechild javascript (25)
¿Cómo hago para eliminar todos los elementos secundarios de un nodo DOM en JavaScript?
Digamos que tengo el siguiente HTML (feo):
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
Y me agarro al nodo que quiero como asi:
var myNode = document.getElementById("foo");
¿Cómo podría eliminar los hijos de foo
para que quede solo <p id="foo"></p>
?
¿Podría simplemente hacer:
myNode.childNodes = new Array();
¿O debería estar usando 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 para DOM.
Utilice 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 se lee mucho mejor que las versiones anteriores.
La mayoría de los usuarios deben tener navegadores modernos o puede transpilar hacia abajo si es necesario.
Soporte del navegador - 91% Abr 2018
¿Por qué no estamos siguiendo el método más simple aquí "eliminar" en bucle dentro mientras.
const foo = document.querySelector(".foo");
while (foo.firstChild) {
foo.firstChild.remove();
}
- Seleccionando el div padre
- Utilizando el método "eliminar" dentro de un bucle While para eliminar el primer elemento secundario, hasta que no quede ninguno.
Aquí hay otro enfoque:
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();
}
El más rápido...
var removeChilds = function (node) {
var last;
while (last = node.lastChild) node.removeChild(last);
};
Gracias a Andrey Lushnikov por jsperf.com/innerhtml-vs-removechild/15 (¡sitio genial!).
En general, JavaScript utiliza matrices para hacer referencia a listas de nodos DOM. Por lo tanto, esto funcionará bien si tiene interés en hacerlo a través de la matriz HTMLElements. También, vale la pena señalar, porque estoy usando una referencia de matriz en lugar de los proto de JavaScript, esto debería funcionar en cualquier navegador, incluido IE.
while(nodeArray.length !== 0) {
nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
En respuesta a DanMan, Maarten y Matt. La clonación de un nodo para establecer el texto es, de hecho, una forma viable en mis resultados.
// @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 );
También funciona para los nodos que no están en el dominio, que devuelven un valor nulo cuando se intenta acceder al nodo principal. 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.
// @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 );
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.
Este es un javascript puro que estoy usando no jQuery pero funciona en todos los navegadores, incluso 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);
}
})
o simplemente puedes hacer esto
document.getElementById("my_button").addEventListener("click",function(){
let parent_node =document.getElemetById("my_div");
parent_node.innerHTML ="";
})
Esto es lo que suelo hacer:
HTMLElement.prototype.empty = function() {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
Y listo, más adelante puedes vaciar cualquier elemento dom con:
anyDom.empty()
Hay un par de opciones para lograrlo:
El más rápido ():
while (node.lastChild) {
node.removeChild(node.lastChild);
}
Alternativas (más lentas):
while (node.firstChild) {
node.removeChild(node.firstChild);
}
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
La forma más fácil:
let container = document.getElementById("containerId");
container.innerHTML = "";
La forma más sencilla de eliminar los nodos secundarios de un nodo a través de Javascript
var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
myNode.removeChild(myNode.lastChild);
}
La respuesta actualmente aceptada es incorrecta acerca de innerHTML es más lento (al menos en IE y Chrome), como m93a se menciona correctamente.
Chrome y FF son mucho más rápidos con este método (que destruirá los datos de jquery adjuntos):
var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode ,node);
en un segundo lejano 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 solución aquí: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
El método de manipulación de 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 internalHTML, excepto por el valor atípico, jquery (1.1.1 y 3.1.1), que es considerablemente más lento que cualquier otra cosa:
$(node).empty();
Pruebas 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 (la nueva url para el reinicio de jsperf porque editar la url antigua no funciona)
El "per-test-loop" de Jsperf a menudo se entiende como "per-iteration", y solo la primera iteración tiene nodos para eliminar, por lo que los resultados no tienen sentido, al momento de la publicación hubo pruebas en este hilo configuradas incorrectamente.
Opción 1 (mucho más lento, ver comentarios más abajo):
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);
}
Otras formas en jQuery.
var foo = $("#foo");
foo.children().remove();
or
$("*", foo ).remove();
or
foo.html("");
Si quieres volver a poner algo en esa div
, probablemente el innerHTML
sea mejor.
Mi ejemplo
<ul><div id="result"></div></ul>
<script>
function displayHTML(result){
var movieLink = document.createElement("li");
var t = document.createTextNode(result.Title);
movieLink.appendChild(t);
outputDiv.appendChild(movieLink);
}
</script>
Si uso el método .firstChild
o .lastChild
, la función displayHTML()
no funciona después, pero no hay problema con el método .innerHTML
.
Si solo quieres tener el nodo sin sus hijos, también puedes hacer una copia de este modo:
var dupNode = document.getElementById("foo").cloneNode(false);
Depende de lo que estés tratando de lograr.
Si usas jQuery:
$(''#foo'').empty();
Si no lo haces
var foo = document.getElementById(''foo'');
while (foo.firstChild) foo.removeChild(foo.firstChild);
Uso simple y rápido para bucle !!
var myNode = document.getElementById("foo");
for(var i = myNode.childNodes.length - 1; i >= 0; --i) {
myNode.removeChild(myNode.childNodes[i]);
}
Esto no funcionará en la etiqueta <span>
!
con jQuery:
$("#foo").find("*").remove();
innerText es el ganador! http://jsperf.com/innerhtml-vs-removechild/133 . En todas las pruebas anteriores, el dom interno del nodo principal se eliminó en la primera iteración y luego en innerHTML o removeChild donde se aplicó a un div vacío.
simplemente solo IE:
parentElement.removeNode(true);
true
- significa hacer remoción profunda - lo que significa que todos los niños también son removidos
vi gente haciendo
while (el.firstNode) {
el.removeChild(el.firstNode);
}
entonces alguien dijo que usar el.lastNode
es más rápido
Sin embargo, creo que este es el más rápido:
var children = el.childNodes;
for (var i=children.length - 1; i>-1; i--) {
el.removeNode(children[i]);
}
¿Qué piensas?
ps: este tema fue un salvavidas para mí. mi complemento de Firefox se rechazó porque utilicé innerHTML. Ha sido un hábito durante mucho tiempo. entonces me di cuenta de esto. Y realmente noté una diferencia de velocidad. en la carga, el innerhtml tardó un poco en actualizarse, sin embargo, ¡va por addElement en su instante!
element.textContent = '''';
Es como el texto interior, excepto el estándar. Es un poco más lento que removeChild()
, pero es más fácil de usar y no hará una gran diferencia de rendimiento si no tienes muchas cosas que eliminar.
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
}
}
}
Esto eliminará todos los nodos dentro del elemento.
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;
while( fc ) {
myNode.removeChild( fc );
fc = myNode.firstChild;
}
Si hay alguna posibilidad de que tenga descendientes afectados por jQuery, entonces debe usar algún método que limpie los datos de jQuery.
$(''#foo'').empty();
El .empty()
jQuery .empty()
garantizará que todos los datos que jQuery asocie con los elementos que se eliminen se eliminarán.
Si simplemente utiliza los métodos DOM
para eliminar los elementos secundarios, los datos permanecerán.