Eliminar elemento por id

1129

Al eliminar un elemento con JavaScript estándar, primero debe ir a su padre:

var element = document.getElementById("element-id");
element.parentNode.removeChild(element);

Tener que ir al nodo principal primero me parece un poco extraño, ¿hay alguna razón por la que JavaScript funcione así?

Zaz
fuente
534
Como dijo James, el DOM no admite la eliminación directa de un objeto. Tienes que ir a su padre y eliminarlo de allí. Javascript no permitirá que un elemento se suicide, pero sí permite el infanticidio ...
Mark Henderson
21
¿Hay una razón? Richard Feynman dice que no . (Bueno, la justificación técnica es fácil de ver si ha escrito algún programa de estructura de árbol. El niño debe informar al padre de todos modos, de lo contrario, la estructura de árbol puede estar rota. Dado que debe hacerlo internamente de todos modos, si le proporciona una función de una línea , es una función conveniente para usted que también puede definirse.)
kizzx2
66
La única razón por la que veo es que siempre debe haber un elemento raíz en un documento xml / xhtml, por lo que no podrá eliminarlo porque no tiene un padre
Alex K
55
Me gusta bastante la solución de Johan , y no estoy seguro de por qué esas funciones no se proporcionan de forma nativa. Como lo demuestra la cantidad de espectadores, es una operación muy común.
Zaz
12
Puede usar element.remove()directamente a partir de ES5. ¡No necesitas al padre!
Gibolt

Respuestas:

659

Sé que aumentar las funciones DOM nativas no siempre es la mejor solución o la más popular, pero esto funciona bien para los navegadores modernos.

Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

Y luego puedes eliminar elementos como este

document.getElementById("my-element").remove();

o

document.getElementsByClassName("my-elements").remove();

Nota: esta solución no funciona para IE 7 y versiones inferiores. Para obtener más información sobre cómo extender el DOM, lea este artículo .

EDITAR : Revisando mi respuesta en 2019, node.remove()ha venido al rescate y se puede usar de la siguiente manera (sin el polyfill anterior):

document.getElementById("my-element").remove();

o

[...document.getElementsByClassName("my-elements")].map(n => n && n.remove());

Estas funciones están disponibles en todos los navegadores modernos (no en IE). Lea más sobre MDN .

Johan Dettmar
fuente
3
¿No debería ser [document.getElementsByClassName ("my-elements") [0] .remove (); ] Creo que la función remove () no está implementada por arrays. Para eliminar todos los elementos de una clase o cualquier selector que devuelva una matriz, debe iterar a través de todos los elementos y llamar a remove () en cada uno.
Sedat Kilinc
1
@SedatKilinc, ¿probaste el fragmento real? No hay matrices involucradas, sino más bien NodeListo HTMLCollectionque son un conjunto de elementos tipo matriz. La segunda definición del método permite eliminar estos "conjuntos de elementos".
Johan Dettmar
1
Ejecutar esto en la consola de Chrome solo parece eliminar un elemento a la vez cuando se usa document.getElementsByClassName("my-elements").remove();. Editar: en realidad elimina un montón, pero requiere volver a ejecutarse para terminar. Pruébelo en esta página con la clase "comentario-copia".
DanielST
2
@slicedtoad tienes razón, mi mal. Modifiqué la función para recorrer hacia atrás a través de los elementos. Parece funcionar bien. El comportamiento del que está hablando probablemente se deba a índices actualizados.
Johan Dettmar
1
No hagas esto. Simplemente elimine los elementos de la forma en que el idioma pretende. Cualquier persona familiarizada con el análisis XML reconocerá la necesidad de llegar al padre para eliminar los hijos. HTML es un superconjunto de XML (más o menos).
Hal50000
283

Crossbrowser e IE> = 11:

document.getElementById("element-id").outerHTML = "";
usuario2192293
fuente
3
Esta parece la solución más simple, confiable y rápida. No necesito eliminar el elemento, así que omito la última línea, pero eso no debería agregar ninguna sobrecarga de ninguna manera. Nota : Encontré esto al intentar encontrar una $.readyalternativa más rápida que js a las noscriptetiquetas. Para usarlo como quería, tuve que envolverlo en una setTimeoutfunción de 1 ms . Esto resuelve todos mis problemas a la vez. Gracias
dgo
Tenga en cuenta outerHTMLque todavía es una nueva (er) adición al estándar. Si está buscando soporte en cualquier software> 6 al momento de escribir, necesitará otra solución. La removefunción mencionada por otros es un caso similar. Como de costumbre, es seguro implementar un polyfill.
Super Cat
delete elementno hace nada ya que no puede eliminar variables en JS, solo teclas;) Verifique usted mismo que no funciona console.log(element)después de delete element...
Ivan Kleshnin
2
Esto es un poco más lento que removeChild(aproximadamente 6-7% en mi sistema). Ver jsperf.com/clear-outerhtml-v-removechild/2
Alejandro García Iglesias
1
Esto podría dejar un espacio donde solía estar un iframe si eso es lo que está tratando de eliminar.
lacostenycoder
164

Puede hacer una removefunción para no tener que pensar en ello cada vez:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}
xsznix
fuente
12
Si desea la línea única sin globalizarse, puede cambiar elema remove.elem. De esa manera, la función se hace referencia a sí misma, por lo que no tiene que crear otra variable global. :-)
twiz
44
Entonces, ¿por qué necesita devolver el elemento? ¿Por qué no?function remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Zach Lysobey
44
@ZachL: Si bien su solución puede parecer más obvia, realiza dos búsquedas DOM que es más lenta y algo que las otras soluciones parecen querer evitar.
Wk_of_Angmar
3
No funciona. Demasiados errores Esto funciona: var elem = document.getElementById ('id'); elem.parentNode.removeChild (elem);
Mitch Match
2
Wow, por qué tan complicado. Simplemente pase el elemento a la función en lugar de una cadena de identificación. De esta manera, el elemento es accesible en toda la función, además de que permanece en una línea
David Fariña
97

Es lo que admite el DOM . Busque en esa página "eliminar" o "eliminar" y removeChild es el único que elimina un nodo.

Christian Sirolli
fuente
13
Eso responde a mi pregunta original, pero ¿por qué funciona JavaScript así?
Zaz
55
Solo estoy adivinando aquí, pero supongo que tiene que ver con la gestión de la memoria. El nodo principal probablemente contiene una lista de punteros a los nodos secundarios. Si acaba de eliminar un nodo (sin usar el padre), el padre aún mantendría el puntero y provocaría una pérdida de memoria. Entonces, la API te obliga a llamar a una función en el padre para eliminar al hijo. Esto también es bueno porque puede caminar el árbol hacia abajo a través de los nodos secundarios llamando a eliminar en cada uno de ellos, y sin pérdida de memoria.
Chadams
2
Hola chicos, aunque esa referencia no tiene esto, lo encontré accidentalmente. la escritura element.remove();funcionará. Quizás sea algo nuevo. Pero la primera vez para mí y funciona. Creo que debería haber funcionado siempre, ya que es muy básico, debe tener cosas.
Muhammad Umer
1
Pero no funciona en IE7 y versiones inferiores. Desde IE7 y versiones posteriores, remove () no funciona
fanfan1609
1
Si tuviera que adivinar, la razón por la que funciona así es que los elementos DOM no pueden eliminarse. Estás quitando la alfombra proverbial de debajo de sus pies. Tienes que sacarlo del contenedor. Al menos así es como trato de pensarlo.
PhilT
82

El DOM está organizado en un árbol de nodos, donde cada nodo tiene un valor, junto con una lista de referencias a sus nodos secundarios. Entonces element.parentNode.removeChild(element)imita exactamente lo que está sucediendo internamente: primero va al nodo primario, luego elimina la referencia al nodo secundario.

A partir de DOM4, se proporciona una función de ayuda a hacer la misma cosa: element.remove(). Esto funciona en el 87% de los navegadores (a partir de 2016), pero no en IE 11. Si necesita admitir navegadores antiguos, puede:

Zaz
fuente
2
No "modifique las funciones DOM nativas" .
Emile Bergeron
36

Para eliminar un elemento:

 var elem = document.getElementById("yourid");
 elem.parentElement.removeChild(elem);

Para eliminar todos los elementos con, por ejemplo, un nombre de clase determinado:

 var list = document.getElementsByClassName("yourclassname");
 for(var i = list.length - 1; 0 <= i; i--)
 if(list[i] && list[i].parentElement)
 list[i].parentElement.removeChild(list[i]);
csjpeter
fuente
Esto está bien cubierto por las respuestas existentes.
KyleMit
44
+1 Por ejemplo simple de eliminación por nombre de clase. Esto no está bien cubierto por las otras respuestas
Louise Eggleton
¿Por qué es if(list[i] && list[i].parentElement)necesaria la línea? ¿No está garantizada la existencia de cada elemento por el hecho de que fue devuelto por el getElementsByClassNamemétodo?
Hidrotermal
Desafortunadamente, la existencia no está realmente garantizada hasta donde yo sé, pero no conozco los detalles al respecto. Acabo de experimentar un valor nulo o indefinido extraño una vez, y puse ese cheque allí sin más investigación. Así que esto es un poco de pirateo.
csjpeter
Debería serdocument.getElementsByClassName(...
Trabajador
21

puedes usar element.remove()

Sai Sunder
fuente
13
element.remove()no es JavaScript válido y solo funciona en ciertos navegadores como Chrome .
Zaz
44
Josh, es javascript válido, excepto que solo Firefox y Chrome lo implementaron (Ver MDN)
Tim Nguyen
10
Lo malo element.remove() es que es JavaScript válido con DOM4 y funciona en todos los navegadores modernos, naturalmente, con excepción de Internet Explorer.
Zaz
24
Funciona bien en Firefox y Chrome. a quién le importa IE
Arun Sharma
13
¡Las personas con trabajo se preocupan por IE!
sqram
18

El ChildNode.remove()método elimina el objeto del árbol al que pertenece.

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Aquí hay un violín que muestra cómo puedes llamar document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

** **

No hay necesidad de extender NodeList. Ya se ha implementado.

** **

Alex Fallenstedt
fuente
2
¡Tenga en cuenta que esto no es compatible con ninguna versión de IE!
MacroMan
1
Si todavía está desarrollando para IE, lo siento mucho por usted.
Alex Fallenstedt
¿No desarrollas para IE? Lo siento mucho por sus clientes o clientes.
MacroMan
13

Puede eliminar directamente ese elemento utilizando el remove()método de DOM.

Aquí hay un ejemplo:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();
Code Cooker
fuente
7

Tener que ir al nodo principal primero me parece un poco extraño, ¿hay alguna razón por la que JavaScript funcione así?

El nombre de la función es removeChild(), y ¿cómo es posible eliminar al hijo cuando no hay padre? :)

Por otro lado, no siempre tiene que llamarlo como lo ha mostrado. element.parentNodees solo un ayudante para obtener el nodo padre del nodo dado. Si ya conoce el nodo padre, puede usarlo así:

Ex:

// Removing a specified element when knowing its parent node
var d = document.getElementById("top");
var d_nested = document.getElementById("nested");
var throwawayNode = d.removeChild(d_nested);

https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild

================================================== =======

Para agregar algo más:

Algunas respuestas han señalado que en lugar de usar parentNode.removeChild(child);, puedes usar elem.remove();. Pero como he notado, hay una diferencia entre las dos funciones, y no se menciona en esas respuestas.

Si lo usa removeChild(), devolverá una referencia al nodo eliminado.

var removedChild = element.parentNode.removeChild(element); 
console.log(removedChild); //will print the removed child.

Pero si lo usa elem.remove();, no le devolverá la referencia.

var el = document.getElementById('Example');
var removedChild = el.remove(); //undefined

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Este comportamiento se puede observar en Chrome y FF. Creo que vale la pena notar :)

Espero que mi respuesta agregue algo de valor a la pregunta y sea útil.

Nimeshka Srimal
fuente
6

Las funciones que usan ele.parentNode.removeChild (ele) no funcionarán para los elementos que ha creado pero que aún no se han insertado en el HTML. Las bibliotecas como jQuery y Prototype utilizan sabiamente un método como el siguiente para evadir esa limitación.

_limbo = document.createElement('div');
function deleteElement(ele){
    _limbo.appendChild(ele);
    _limbo.removeChild(ele);
}

Creo que JavaScript funciona así porque los diseñadores originales del DOM consideraban que la navegación padre / hijo y la navegación anterior / siguiente eran una prioridad más alta que las modificaciones DHTML que son tan populares hoy en día. Poder leer de un <input type = 'text'> y escribir en otro por ubicación relativa en el DOM fue útil a mediados de los 90, un momento en que la generación dinámica de formularios HTML completos o elementos de GUI interactivos apenas era un centelleo El ojo de algún desarrollador.

Psudo
fuente
3

Tener que ir al nodo principal primero me parece un poco extraño, ¿hay alguna razón por la que JavaScript funcione así?

En mi humilde opinión: La razón de esto es la misma que he visto en otros entornos: está realizando una acción basada en su "enlace" a algo. No puede eliminarlo mientras está vinculado a él.

Como cortar la rama de un árbol. Siéntese en el lado más cercano al árbol mientras corta o el resultado será ... desafortunado (aunque divertido).

TheSatinKnight
fuente
2

Este en realidad proviene de FireFox ... por una vez, IE estaba por delante del paquete y permitió la eliminación de un elemento directamente.

Esto es solo mi suposición, pero creo que la razón por la que debe eliminar a un niño a través de los padres se debe a un problema con la forma en que FireFox manejó la referencia.

Si llamas a un objeto para cometer hari-kari directamente, inmediatamente después de que muera, aún tienes esa referencia. Esto tiene el potencial de crear varios errores desagradables ... como no eliminarlo, eliminarlo pero mantener referencias que parecen válidas o simplemente una pérdida de memoria.

Creo que cuando se dieron cuenta del problema, la solución fue eliminar un elemento a través de su elemento primario porque cuando el elemento desapareció, ahora simplemente tiene una referencia al elemento primario. Esto detendría toda esa molestia y, por ejemplo, si se cierra un árbol nodo por nodo, se 'cerraría' bastante bien.

Debería ser un error fácilmente reparable, pero al igual que con muchas otras cosas en la programación web, el lanzamiento probablemente se apresuró, lo que llevó a esto ... y cuando llegó la próxima versión, suficientes personas lo estaban usando para cambiar esto. a romper un montón de código.

Nuevamente, todo esto es simplemente mi conjetura.

Sin embargo, espero con ansias el día en que la programación web finalmente obtenga una limpieza completa de primavera, se limpien todas estas pequeñas idiosincrasias extrañas y todos comiencen a jugar con las mismas reglas.

Probablemente el día después de que mi criado robot me demanda por salarios atrasados.

SilentThunderStorm
fuente
10
Dudo que Firefox sea responsable de esto. removeChildes un método de la interfaz DOM Nivel 1Node .
Felix Kling
0
// http://javascript.crockford.com/memory/leak.html
// cleans dom element to prevent memory leaks
function domPurge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            domPurge(d.childNodes[i]);
       }
    }
}

function domRemove(id) {
    var elem = document.getElementById(id);
    domPurge(elem);
    return elem.parentNode.removeChild(elem);
}
Will Farrell
fuente
-3

Esta es la mejor función para eliminar un elemento sin error de script:

function Remove(EId)
{
    return(EObj=document.getElementById(EId))?EObj.parentNode.removeChild(EObj):false;
}

Nota a EObj=document.getElementById(EId).

Este es UN signo igual no ==.

si EIdexiste un elemento , la función lo elimina; de lo contrario, devuelve falso, no error.

Amin Atabakzadeh
fuente
44
Crea una variable global.
bjb568
1
También es la peor versión de otra respuesta , pero 2 años de retraso.
Emile Bergeron