Remover elemento por ID

1129

Ao remover um elemento com JavaScript padrão, você deve ir primeiro ao pai:

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

Ter que ir primeiro ao nó pai parece um pouco estranho para mim; existe uma razão para o JavaScript funcionar assim?

Zaz
fonte
534
Como James disse, o DOM não suporta a remoção direta de um objeto. Você precisa ir ao pai e removê-lo de lá. Javascript não vai deixar um elemento cometer suicídio, mas ele faz autorização infanticídio ...
Mark Henderson
21
Existe uma razão? Richard Feynman diz que não . (Bem, a justificativa técnica é fácil de ver se você escreveu algum programa de estrutura de árvore. O filho deve informar o pai de qualquer maneira, caso contrário, a estrutura da árvore pode ser quebrada. Como deve ser feita internamente de qualquer maneira, se você fornecer uma função de uma linha , é apenas uma função conveniente para você que você pode também definir a si mesmo).
kizzx2
6
A única razão que eu vejo é que deve haver sempre um elemento de raiz em um documento XML / XHTML, então você não será capaz de removê-lo, porque ele não tem um pai
Alex K
5
Gosto bastante da solução alternativa de Johan e não sei por que essas funções não são fornecidas nativamente. Como evidenciado pelo número de espectadores, é uma operação muito comum.
Zaz
12
Você pode usar element.remove()diretamente a partir do ES5. Você não precisa dos pais!
Gibolt

Respostas:

659

Sei que aumentar as funções DOM nativas nem sempre é a melhor ou a mais popular solução, mas isso funciona bem para 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]);
        }
    }
}

E então você pode remover elementos como este

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

ou

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

Nota: esta solução não funciona para o IE 7 e abaixo. Para mais informações sobre como estender o DOM, leia este artigo .

Edição : Revendo minha resposta em 2019, node.remove()chegou ao resgate e pode ser usada da seguinte maneira (sem o polyfill acima):

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

ou

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

Essas funções estão disponíveis em todos os navegadores modernos (não no IE). Leia mais sobre MDN .

Johan Dettmar
fonte
3
Não deveria ser [document.getElementsByClassName ("my-elements") [0] .remove (); ] Eu acho que a função remove () não é implementada por matrizes. Para remover todos os elementos de uma classe ou qualquer seletor que retorne uma matriz, você precisa percorrer todos os elementos e chamar remove () em cada um.
precisa saber é o seguinte
1
@SedatKilinc, você tentou o snippet real? Não há matrizes envolvidas, mas sim NodeListou HTMLCollectionque são um conjunto de elementos do tipo matriz. A segunda definição de método permite que esses "conjuntos de elementos" sejam removidos.
Johan Dettmar
1
A execução disso no console do Chrome parece excluir apenas um elemento de cada vez ao usar document.getElementsByClassName("my-elements").remove();. Editar: na verdade, ele exclui um monte, mas requer a execução novamente para concluir. Experimente nesta página com a classe "comment-copy".
DanielST
2
@slicedtoad você está certo, meu mal. Modifiquei a função para fazer um loop para trás através dos elementos. Parece funcionar bem. O comportamento do qual você está falando provavelmente é causado por índices atualizados.
Johan Dettmar
1
Não faça isso. Simplesmente remova os itens da maneira que o idioma pretender. Qualquer pessoa familiarizada com a análise de XML reconhecerá a necessidade de chegar ao pai para excluir filhos. HTML é um superconjunto de XML (mais ou menos).
precisa saber é o seguinte
283

Crossbrowser e IE> = 11:

document.getElementById("element-id").outerHTML = "";
user2192293
fonte
3
Essa parece a solução mais simples, confiável e rápida. Não preciso excluir o elemento, por isso pulo a última linha, mas isso não deve adicionar nenhuma sobrecarga de qualquer maneira. Nota : Encontrei isso ao tentar encontrar uma $.readyalternativa mais rápida do que js para as noscripttags. Para usá-lo como eu queria, tive que envolvê-lo em uma setTimeoutfunção de 1ms . Isso resolve todos os meus problemas de uma só vez. Gracias.
Dgo
Lembre- outerHTMLse de que ainda é uma nova adição ao padrão. Se você estiver procurando por suporte para qualquer software> 6 no momento da redação, precisará de outra solução. A removefunção mencionada por outros é um caso semelhante. Como de costume, é seguro implementar um polyfill.
Super Cat
delete elementnão faz nada, como você pode não variáveis de exclusão em JS, apenas chaves;) Verifique por si mesmo ele não funciona por console.log(element)depois delete element...
Ivan Kleshnin
2
Isso é um pouco mais lento que removeChild(cerca de 6-7% no meu sistema). Veja jsperf.com/clear-outerhtml-v-removechild/2
Alejandro García Iglesias,
1
Isso pode deixar um espaço onde um iframe costumava estar, se é isso que você está tentando remover.
lacostenycoder 13/03
164

Você poderia criar uma removefunção para não precisar pensar nisso toda vez:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}
xsznix
fonte
12
Se você deseja uma linha sem se tornar global, pode mudar elempara remove.elem. Dessa forma, a função se referencia a si mesma, para que você não precise criar outra variável global. :-)
twiz 27/12/12
4
então, por que você precisa devolver o elem? Por que nãofunction remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Zach Lysobey
4
@ZachL: Embora sua solução possa parecer mais óbvia, ela realiza duas pesquisas de DOM mais lentas e algo que as outras soluções parecem querer evitar.
Wk_of_Angmar 01/07/2013
3
Não funciona. Muitos erros. Isso funciona: var elem = document.getElementById ('id'); elem.parentNode.removeChild (elem);
Mitch Match
2
Uau, por que tão complicado. Apenas passe o próprio elemento para a função em vez de uma sequência de id. Dessa forma, o elemento é acessível em toda a função, além de permanecer um alinhador
David Fariña
97

É o que o DOM suporta . Pesquise nessa página por "remover" ou "excluir" e removeChild é o único que remove um nó.

Christian Sirolli
fonte
13
Isso responde à minha pergunta original, mas por que o JavaScript funciona assim?
Zaz
5
Só estou supondo aqui, mas eu diria que isso tem a ver com gerenciamento de memória. O nó pai provavelmente mantém uma lista de ponteiros para os nós filhos. Se você acabou de excluir um nó (sem usar o pai), o pai ainda manteria o ponteiro e causaria um vazamento de memória. Portanto, a API força você a chamar uma função no pai para excluir o filho. isso também é bom porque pode percorrer a árvore pelos nós filhos chamando remove em cada um deles, e não vazando memória.
Chadams
2
ei pessoal, mesmo que essa referência não tenha isso, eu achei acidentalmente. a escrita element.remove();irá funcionar. Talvez seja algo novo. Mas a primeira vez para mim e funciona. Eu acho que deveria ter funcionado sempre, pois é muito básico, deve ter coisas.
Muhammad Umer
1
Mas isso não funciona no IE7 e abaixo. A partir do IE7 e abaixo, remove () não funciona #
fanfan1609 /
1
Se eu tivesse que adivinhar, a razão pela qual funciona dessa maneira é que os elementos DOM não podem se remover. Você está removendo o proverbial tapete de baixo dos pés. Você precisa removê-lo do contêiner. Pelo menos é assim que eu tento pensar nisso.
PhilT
82

O DOM está organizado em uma árvore de nós, em que cada nó tem um valor, juntamente com uma lista de referências aos seus nós filhos. Portanto, element.parentNode.removeChild(element)imita exatamente o que está acontecendo internamente: primeiro, você acessa o nó pai e remove a referência ao nó filho.

A partir de DOM4, uma função auxiliar é fornecida para fazer a mesma coisa: element.remove(). Isso funciona em 87% dos navegadores (a partir de 2016), mas não no IE 11. Se você precisar oferecer suporte a navegadores antigos, poderá:

Zaz
fonte
2
Por favor, não "modifique as funções DOM nativas" .
Emile Bergeron
36

Para remover um elemento:

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

Para remover todos os elementos com, por exemplo, um determinado nome de 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]);
csjpeter
fonte
Isso é bem coberto pelas respostas existentes.
precisa saber é o seguinte
4
+1 Para um exemplo simples de remoção pelo nome da classe. Esta não é coberto também por outras respostas
Louise Eggleton
Por que a if(list[i] && list[i].parentElement)linha é necessária? A existência de cada elemento não é garantida pelo fato de ter sido retornado pelo getElementsByClassNamemétodo?
Hydrothermal
Infelizmente, a existência não é realmente garantida, tanto quanto eu sei, mas não conheço os detalhes. Acabei de experimentar um valor nulo indefinido ou nulo estranho uma vez e coloquei essa verificação lá sem mais investigações. Então isso é um pouco de hack.
csjpeter
Deveria serdocument.getElementsByClassName(...
Trabalhador
21

você pode apenas usar element.remove()

Sai Sunder
fonte
13
element.remove()não é JavaScript válido e funciona apenas em alguns navegadores, como o Chrome .
Zaz
4
Josh, é javascript válido, com exceção apenas Firefox e Chrome implementadas (ver MDN)
Tim Nguyen
10
Meu mal, element.remove() é JavaScript válido com DOM4 e funciona em todos os navegadores modernos, naturalmente, com exceção do Internet Explorer.
Zaz
24
Funcionando bem no FireFox e Chrome. quem se importa com o IE
Arun Sharma
13
pessoas com empregos se preocupam com o IE!
Sqram
18

O ChildNode.remove()método remove o objeto da árvore à qual ele pertence.

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

Aqui está um violino que mostra como você pode ligar document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

Não há necessidade de estender o NodeList. Já foi implementado.

**

Alex Fallenstedt
fonte
2
Observe que isso não é suportado em nenhuma versão do IE!
Macroman
1
Se você ainda está desenvolvendo para o IE, sinto muito por você.
Alex Fallenstedt 18/10/19
Você não desenvolve para o IE? Sinto muito por seus clientes ou clientes.
Macroman
13

Você pode remover diretamente esse elemento usando o remove()método DOM.

aqui está um exemplo:

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

Ter que ir primeiro ao nó pai parece um pouco estranho para mim; existe uma razão para o JavaScript funcionar assim?

O nome da função é removeChild()e como é possível remover o filho quando não há pai? :)

Por outro lado, você nem sempre precisa chamá-lo como mostrou. element.parentNodeé apenas um auxiliar para obter o nó pai do nó fornecido. Se você já conhece o nó pai, pode usá-lo da seguinte maneira:

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 adicionar algo mais:

Algumas respostas apontaram que, em vez de usar parentNode.removeChild(child);, você pode usar elem.remove();. Mas como eu notei, há uma diferença entre as duas funções, e isso não é mencionado nessas respostas.

Se você usar removeChild(), ele retornará uma referência ao nó removido.

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

Mas se você usar elem.remove();, não retornará a referência.

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

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

Esse comportamento pode ser observado no Chrome e no FF. Eu acredito que vale a pena notar :)

Espero que minha resposta agregue algum valor à pergunta e seja útil!

Nimeshka Srimal
fonte
6

As funções que usam ele.parentNode.removeChild (ele) não funcionarão para elementos que você criou, mas ainda não inseriu no HTML. Bibliotecas como jQuery e Prototype sabiamente usam um método como o seguinte para evitar essa limitação.

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

Penso que o JavaScript funciona assim porque os designers originais do DOM consideravam a navegação pai / filho e a navegação anterior / seguinte como uma prioridade mais alta do que as modificações DHTML que são tão populares hoje em dia. Ser capaz de ler de um <input type = 'text'> e escrever para outro por localização relativa no DOM foi útil em meados dos anos 90, uma época em que a geração dinâmica de formulários HTML inteiros ou elementos interativos da GUI quase não brilhava. olho de algum desenvolvedor.

Psudo
fonte
3

Ter que ir primeiro ao nó pai parece um pouco estranho para mim; existe uma razão para o JavaScript funcionar assim?

IMHO: A razão para isso é a mesma que já vi em outros ambientes: você está executando uma ação com base no seu "link" para algo. Você não pode excluí-lo enquanto estiver vinculado a ele.

Como cortar um galho de árvore. Sente-se no lado mais próximo da árvore durante o corte ou o resultado será ... infeliz (embora engraçado).

TheSatinKnight
fonte
2

Este, na verdade, vem do FireFox ... pela primeira vez, o IE estava à frente do pacote e permitiu a remoção de um elemento diretamente.

Essa é apenas minha suposição, mas acredito que a razão pela qual você deve remover um filho através dos pais deve-se a um problema com a maneira como o FireFox lidou com a referência.

Se você chama um objeto para confirmar o hari-kari diretamente, imediatamente após a morte, você ainda mantém essa referência a ele. Isso tem o potencial de criar vários erros desagradáveis ​​... como não removê-lo, removê-lo, mas mantendo referências válidas ou simplesmente um vazamento de memória.

Acredito que, quando eles perceberam o problema, a solução alternativa era remover um elemento por meio do pai, porque, quando o elemento desapareceu, você agora está simplesmente mantendo uma referência ao pai. Isso interromperia todo esse desagradável e (se o fechamento de um nó de árvore por nó, por exemplo) seria "bastante eficiente".

Deveria ser um bug facilmente corrigível, mas, como em muitas outras coisas na programação da web, o lançamento provavelmente foi apressado, levando a isso ... e quando a próxima versão apareceu, havia pessoas o usando para mudar isso. para quebrar um monte de código.

Novamente, tudo isso é simplesmente meu palpite.

No entanto, aguardo com expectativa o dia em que a programação na Web finalmente terá uma limpeza completa na primavera, todas essas pequenas idiossincrasias estranhas serão limpas e todos começarão a jogar pelas mesmas regras.

Provavelmente no dia seguinte ao meu servo-robô me processar por salários atrasados.

SilentThunderStorm
fonte
10
Duvido que o Firefox seja responsável por isso. removeChildé um método da interface do nível 1Node do DOM .
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);
}
será Farrell
fonte
-3

Esta é a melhor função para remover um elemento sem erro de script:

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

Nota para EObj=document.getElementById(EId).

Este é um sinal de igual que não ==.

se o elemento EIdexiste, a função o remove; caso contrário, retorna false, não error.

Amin Atabakzadeh
fonte
4
Cria uma variável global.
Bjb568 17/05
1
É também a pior versão de outra resposta , mas com dois anos de atraso.
Emile Bergeron