Rimuovi elemento per ID


1129

Quando rimuovi un elemento con JavaScript standard, devi prima andare al suo genitore:

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

Dover passare prima al nodo padre mi sembra un po 'strano, c'è un motivo per cui JavaScript funziona in questo modo?


534
Come ha detto James, il DOM non supporta la rimozione diretta di un oggetto. Devi andare dal suo genitore e rimuoverlo da lì. Javascript non permetterà a un elemento di suicidarsi, ma permette l'infanticidio ...
Mark Henderson,

21
C'è una ragione? Richard Feynman dice di no . (Beh, la giustificazione tecnica è facile da vedere se hai scritto dei programmi di struttura ad albero. Il bambino deve comunque informare il genitore altrimenti la struttura ad albero potrebbe essere rotta. Dato che deve farlo comunque internamente, se ti ha fornito una funzione di una riga , è solo una comoda funzione per te che potresti anche definire te stesso.)
kizzx2

6
L'unica ragione per cui vedo è che dovrebbe esserci sempre un elemento radice in un documento xml / xhtml, quindi non sarai in grado di rimuoverlo perché non ha un genitore
Alex K

5
Mi piace molto la soluzione alternativa di Johan , e non sono sicuro del perché tali funzioni non siano fornite in modo nativo. Come evidenziato dal numero di spettatori, è un'operazione molto comune.
Zaz,

12
È possibile utilizzare element.remove()direttamente da ES5. Non hai bisogno del genitore!
Gibolt,

Risposte:


659

So che aumentare le funzioni DOM native non è sempre la soluzione migliore o più popolare, ma funziona bene per i browser moderni.

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]);
        }
    }
}

E quindi puoi rimuovere elementi come questo

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

o

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

Nota: questa soluzione non funziona per IE 7 e versioni precedenti. Per maggiori informazioni sull'estensione del DOM leggi questo articolo .

EDIT : rivedere la mia risposta nel 2019, node.remove()è venuto in soccorso e può essere utilizzato come segue (senza il polyfill sopra):

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

o

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

Queste funzioni sono disponibili in tutti i browser moderni (non IE). Ulteriori informazioni su MDN .


3
Non dovrebbe essere [document.getElementsByClassName ("my-elements") [0] .remove (); ] Penso che la funzione remove () non sia implementata dagli array. Per rimuovere tutti gli elementi di una classe o qualsiasi selettore che restituisce un array, è necessario scorrere tutti gli elementi e chiamare remove () su ciascuno.
Sedat Kilinc,

1
@SedatKilinc, hai provato lo snippet attuale? Non ci sono array coinvolti, ma piuttosto NodeListo HTMLCollectionche sono un insieme di elementi simili a array. La seconda definizione del metodo consente di rimuovere questi "set di elementi".
Johan Dettmar,

1
L'esecuzione nella console di Chrome sembra eliminare solo un elemento alla volta durante l'utilizzo document.getElementsByClassName("my-elements").remove();. Modifica: in realtà cancella un sacco ma richiede di essere rieseguito per finire. Provalo in questa pagina con la classe "commento-copia".
DanielST

2
@slicedtoad hai ragione, mia cattiva. Ho modificato la funzione per scorrere indietro tra gli elementi. Sembra funzionare bene. Il comportamento di cui stai parlando è molto probabilmente causato da indici aggiornati.
Johan Dettmar,

1
Non farlo Rimuovi semplicemente gli elementi nel modo desiderato dalla lingua. Chiunque abbia familiarità con l'analisi di XML riconoscerà la necessità di contattare il genitore per eliminare i figli. HTML è un superset di XML (sorta di).
Hal50000,

283

Crossbrowser e IE> = 11:

document.getElementById("element-id").outerHTML = "";

3
Questa sembra la soluzione più semplice, affidabile e veloce. Non ho bisogno di eliminare l'elemento, quindi salto l'ultima riga, ma ciò non dovrebbe aggiungere alcun overhead in entrambi i modi. Nota : ho trovato questo mentre cercavo di trovare $.readyun'alternativa più veloce di js ai noscripttag. Per usarlo come volevo, ho dovuto avvolgerlo in una setTimeoutfunzione di 1ms . Questo risolve tutti i miei problemi in una volta. Gracias.
Do

Tieni presente che outerHTMLè ancora una nuova aggiunta alla norma. Se stai cercando supporto su qualsiasi software> 6 al momento della scrittura, avrai bisogno di un'altra soluzione. La removefunzione menzionata da altri è un caso simile. Come al solito è sicuro implementare un polyfill.
Super Cat

delete elementnon fa nulla in quanto non è possibile eliminare le variabili in JS, solo le chiavi;) Verifica tu stesso che non funzioni console.log(element)dopo delete element...
Ivan Kleshnin,

2
Questo è un po 'più lento di removeChild(circa il 6-7% sul mio sistema). Vedi jsperf.com/clear-outerhtml-v-removechild/2
Alejandro García Iglesias,

1
Questo potrebbe lasciare uno spazio in cui si trovava un iframe se è quello che stai cercando di rimuovere.
lacostenycoder

164

Potresti creare una removefunzione in modo da non doverci pensare ogni volta:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}

12
Se vuoi il one-liner senza diventare globale, puoi passare elema remove.elem. In questo modo la funzione fa riferimento a se stessa, quindi non è necessario creare un'altra variabile globale. :-)
twiz

4
quindi, perché è necessario restituire l'elem? Perché nofunction remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Zach Lysobey,

4
@ZachL: anche se la tua soluzione potrebbe sembrare più ovvia, esegue due ricerche DOM più lente e qualcosa che le altre soluzioni sembrano voler evitare.
Wk_of_Angmar,

3
Non funziona. Troppi errori. Funziona: var elem = document.getElementById ('id'); elem.parentNode.removeChild (elem);
Mitch Match

2
Wow, perché così complicato. Basta passare l'elemento stesso alla funzione invece di una stringa id. In questo modo l'elemento è accessibile in tutta la funzione e rimane un liner
David Fariña,

97

È ciò che supporta il DOM . Cerca quella pagina "rimuovi" o "elimina" e rimuoviChild è l'unico che rimuove un nodo.


13
Ciò risponde alla mia domanda originale, ma perché JavaScript funziona in questo modo?
Zaz,

5
Sto solo indovinando qui, ma suppongo che abbia a che fare con la gestione della memoria. Molto probabilmente il nodo padre contiene un elenco di puntatori ai nodi figlio. Se hai appena eliminato un nodo (senza usare parent), il parent manterrebbe comunque il puntatore e causerebbe una perdita di memoria. Quindi l'API ti costringe a chiamare una funzione sul genitore per eliminare il figlio. anche questo è bello perché può percorrere l'albero attraverso i nodi figlio chiamando rimuovendo su ciascuno di essi e senza perdite di memoria.
Chadams,

2
ciao ragazzi, anche se quel riferimento non ha questo, l'ho trovato per caso. la scrittura element.remove();funzionerà. Forse è qualcosa di nuovo. Ma la prima volta per me e funziona. Penso che avrebbe dovuto funzionare sempre perché è molto semplice avere cose.
Muhammad Umer,

1
Ma non funziona in IE7 e versioni successive. Da IE7 in poi, remove () non funziona
fanfan1609,

1
Se dovessi indovinare, la ragione per cui funziona così è che gli elementi DOM non possono rimuoversi. Stai rimuovendo il proverbiale tappeto da sotto i suoi piedi. Devi rimuoverlo dal contenitore. Almeno è così che provo a pensarci.
PhilT,

82

Il DOM è organizzato in un albero di nodi, in cui ogni nodo ha un valore, insieme a un elenco di riferimenti ai suoi nodi figlio. Quindi element.parentNode.removeChild(element)imita esattamente ciò che sta accadendo internamente: prima vai al nodo padre, quindi rimuovi il riferimento al nodo figlio.

Come di DOM4, una funzione di supporto viene fornito per fare la stessa cosa: element.remove(). Questo funziona in 87% dei browser (come del 2016), ma non IE 11. Se è necessario supportare i browser più vecchi, è possibile:


2
Si prega di non "modificare le funzioni DOM native" .
Emile Bergeron

36

Per rimuovere un elemento:

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

Per rimuovere tutti gli elementi con ad esempio un determinato nome di classe:

 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]);

Questo è ben coperto dalle risposte esistenti.
KyleMit,

4
+1 Per un semplice esempio di rimozione per nome della classe. Questo non è ben coperto dalle altre risposte
Louise Eggleton,

Perché la if(list[i] && list[i].parentElement)linea è necessaria? L'esistenza di ciascun elemento non è garantita dal fatto che è stata restituita dal getElementsByClassNamemetodo?
Hydrothermal,

Sfortunatamente, per quanto ne so, l'esistenza non è garantita, ma non ne conosco i dettagli. Ho appena sperimentato uno strano valore indefinito o nullo una volta, e ho messo quel controllo lì senza ulteriori indagini. Quindi questo è un po 'di hack.
csjpeter,

Dovrebbe esseredocument.getElementsByClassName(...
Operaio

21

puoi semplicemente usare element.remove()


13
element.remove()non è JavaScript valido e funziona solo in alcuni browser come Chrome .
Zaz,

4
Josh, è javascript valido, tranne che per Firefox e Chrome implementato (Vedi MDN)
Tim Nguyen,

10
Mio male, element.remove() è JavaScript valido con DOM4 e funziona in tutti i browser moderni, naturalmente ad eccezione di Internet Explorer.
Zaz,

24
Funziona bene su FireFox e Chrome. a chi importa di IE
Arun Sharma,

13
le persone con lavoro si preoccupano di IE!
sqram

18

Il ChildNode.remove()metodo rimuove l'oggetto dall'albero a cui appartiene.

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

Ecco un violino che mostra come si può chiamare document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

Non è necessario estendere NodeList. È già stato implementato.

**


2
Nota, questo non è supportato in nessuna versione di IE!
MacroMan,

1
Se stai ancora sviluppando per IE, mi dispiace molto per te.
Alex Fallenstedt,

Non sviluppi per IE? Mi dispiace molto per i tuoi clienti o clienti.
MacroMan,

13

Puoi rimuovere direttamente quell'elemento usando il remove()metodo DOM.

ecco un esempio:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();


7

Dover passare prima al nodo padre mi sembra un po 'strano, c'è un motivo per cui JavaScript funziona in questo modo?

Il nome della funzione è removeChild()e come è possibile rimuovere il figlio quando non ci sono genitori? :)

D'altra parte, non devi sempre chiamarlo come hai mostrato. element.parentNodeè solo un aiuto per ottenere il nodo genitore del nodo dato. Se conosci già il nodo genitore, puoi semplicemente usarlo in questo modo:

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

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

Per aggiungere qualcosa di più:

Alcune risposte hanno sottolineato che invece di utilizzare parentNode.removeChild(child);, è possibile utilizzare elem.remove();. Ma come ho notato, c'è una differenza tra le due funzioni e non è menzionato in quelle risposte.

Se lo usi removeChild(), restituirà un riferimento al nodo rimosso.

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

Ma se usi elem.remove(); , non ti restituirà il riferimento.

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

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

Questo comportamento può essere osservato in Chrome e FF. Credo che valga la pena notare :)

Spero che la mia risposta aggiunga un valore alla domanda e sarà utile !!


6

Le funzioni che usano ele.parentNode.removeChild (ele) non funzioneranno per gli elementi che hai creato ma non ancora inserito nell'HTML. Le librerie come jQuery e Prototype usano saggiamente un metodo come il seguente per eludere tale limitazione.

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

Penso che JavaScript funzioni così perché i progettisti originali del DOM consideravano il genitore / figlio e la navigazione precedente / successiva una priorità più alta rispetto alle modifiche DHTML che sono così popolari oggi. Essere in grado di leggere da un <input type = 'text'> e scrivere ad un altro in base alla posizione relativa nel DOM è stato utile a metà degli anni '90, un'epoca in cui la generazione dinamica di interi moduli HTML o elementi interattivi della GUI era a malapena un luccichio in l'occhio di alcuni sviluppatori.


3

Dover passare prima al nodo padre mi sembra un po 'strano, c'è un motivo per cui JavaScript funziona in questo modo?

IMHO: La ragione di ciò è la stessa che ho visto in altri ambienti: stai eseguendo un'azione basata sul tuo "link" a qualcosa. Non puoi eliminarlo mentre sei collegato ad esso.

Come tagliare un ramo d'albero. Siedi sul lato più vicino all'albero mentre tagli o il risultato sarà ... sfortunato (anche se divertente).


2

Questo in realtà proviene da FireFox ... per una volta, IE era in vantaggio rispetto al pacchetto e ha permesso la rimozione diretta di un elemento.

Questo è solo il mio presupposto, ma credo che il motivo per cui è necessario rimuovere un figlio tramite il genitore sia dovuto a un problema con il modo in cui FireFox ha gestito il riferimento.

Se chiami un oggetto per commettere direttamente hari-kari, quindi immediatamente dopo la sua morte, stai ancora mantenendo quel riferimento ad esso. Questo ha il potenziale per creare diversi bug cattivi ... come non riuscire a rimuoverlo, rimuoverlo ma mantenendo i riferimenti ad esso che sembrano validi, o semplicemente una perdita di memoria.

Credo che quando hanno capito il problema, il problema era rimuovere un elemento attraverso il suo genitore perché quando l'elemento è sparito, ora stai semplicemente tenendo un riferimento al genitore. Ciò fermerebbe tutta quella spiacevolezza e (se si chiudesse un nodo ad albero per nodo, per esempio) si "comprimerebbe" piuttosto bene.

Dovrebbe essere un bug facilmente risolvibile, ma come per molte altre cose nella programmazione web, il rilascio è stato probabilmente affrettato, portando a questo ... e quando è arrivata la versione successiva, abbastanza persone lo stavano usando che cambiare questo avrebbe portato a rompere un mucchio di codice.

Ancora una volta, tutto questo è semplicemente una mia ipotesi.

Attendo comunque con impazienza il giorno in cui la programmazione web finalmente avrà una completa pulizia primaverile, tutte queste strane idiosincrasie vengono ripulite e tutti iniziano a giocare con le stesse regole.

Probabilmente il giorno dopo il mio servitore di robot mi fa causa per salari arretrati.


10
Dubito che Firefox sia responsabile per questo. removeChildè un metodo del DOM Level 1 Nodeinterfaccia .
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);
}

-3

Questa è la migliore funzione per rimuovere un elemento senza errore di script:

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

Nota a EObj=document.getElementById(EId) .

Questo è UN segno uguale no == .

se l'elemento EIdesiste, la funzione lo rimuove, altrimenti restituisce false, no error.


4
Crea una variabile globale.
bjb568,

1
È anche la versione peggiore di un'altra risposta , ma con 2 anni di ritardo.
Emile Bergeron,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.