Como eu removeria todos os elementos filhos de um nó DOM em JavaScript?
Digamos que eu tenha o seguinte (feio) HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
E eu pego o nó que eu quero assim:
var myNode = document.getElementById("foo");
Como eu poderia remover os filhos de foo
modo a <p id="foo"></p>
restar apenas ?
Eu poderia apenas fazer:
myNode.childNodes = new Array();
ou devo usar alguma combinação de removeElement
?
Eu gostaria que a resposta fosse diretamente DOM; embora pontos extras se você também fornecer uma resposta no jQuery junto com a resposta somente do DOM.
javascript
dom
Polaris878
fonte
fonte
innerHTML = ''
é mais lento, mas não acho que seja "errado". Quaisquer reivindicações de vazamento de memória devem ser apoiadas com evidências.A resposta atualmente aceita está errada em
innerHTML
ser mais lenta (pelo menos no IE e no Chrome), como m93a mencionado corretamente.Chrome e FF são muito mais rápidos usando este método (que destruirá os dados do jquery anexado):
em um segundo distante para FF e Chrome e mais rápido no IE:
O InnerHTML não destruirá seus manipuladores de eventos nem quebrará as referências a jquery , também é recomendado como uma solução aqui: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML .
O método de manipulação do DOM mais rápido (ainda mais lento que os dois anteriores) é a remoção do intervalo, mas os intervalos não são suportados até o IE9.
Os outros métodos mencionados parecem ser comparáveis, mas muito mais lentos que o innerHTML, exceto o jquery (1.1.1 e 3.1.1), que é consideravelmente mais lento que qualquer outra coisa:
Evidência aqui:
http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300https://jsperf.com/remove-all-child-elements-of-a- dom-node-in-javascript (Novo URL para reinicialização do jsperf porque a edição do URL antigo não está funcionando)O "loop por teste" do Jsperf geralmente é entendido como "por iteração", e somente a primeira iteração tem nós para remover, de modo que os resultados não fazem sentido; no momento da postagem, havia testes nesse segmento configurados incorretamente.
fonte
jQuery.cache
, causando um vazamento de memória, porque a única referência disponível para gerenciar esses dados estava nos elementos que você acabou de destruir.cloneNode
alterna o contêiner, o que significa que as referências ao contêiner não são mantidas (jquery ou de outra forma). O cache do Jquery pode valer a pena usar o jquery para remover elementos se você tiver dados do jquery anexados a eles. Espero que eles mudem para o WeakMaps em algum momento. A limpeza (ou mesmo a existência) do $ .cache não parece estar oficialmente documentada.Use Javascript moderno, com
remove
!Essa é uma maneira mais nova de gravar a remoção de nós no ES5. É JS baunilha e lê muito melhor do que as versões anteriores.
A maioria dos usuários deve ter navegadores modernos ou você pode transpilar para baixo, se necessário.
Suporte do navegador - 95% dez 2019
fonte
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
loop. developer.mozilla.org/en-US/docs/Web/API/ParentNode/children developer.mozilla.org/en-US/docs/Web/API/Node/childNodeswhile (parent.firstChild && !parent.firstChild.remove());
[...parent.childNodes].forEach(el => el.remove());
while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); }
Se há alguma chance de que você tem jQuery afetados descendentes, então você deve usar algum método que irá limpar os dados jQuery.
O
.empty()
método jQuery garantirá que todos os dados associados ao jQuery aos elementos removidos sejam limpos.Se você simplesmente usar
DOM
métodos para remover os filhos, esses dados permanecerão.fonte
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Se você usa jQuery:
Se não o fizer:
fonte
O mais rápido...
Obrigado a Andrey Lushnikov pelo link para jsperf.com (site legal!).
EDIT: para ficar claro, não há diferença de desempenho no Chrome entre firstChild e lastChild. A resposta principal mostra uma boa solução para o desempenho.
fonte
Se você quiser apenas ter o nó sem seus filhos, também poderá fazer uma cópia dele assim:
Depende do que você está tentando alcançar.
fonte
parent.replaceChild(cloned, original)
? Isso pode ser mais rápido do que remover filhos um por um e deve funcionar em tudo que suporta o DOM (portanto, todos os tipos de documentos XML, incluindo SVG). Definir innerHTML também pode ser mais rápido do que remover filhos um por um, mas isso não funciona em nada além de documentos HTML. Deve testar isso há algum tempo.addEventListener
.Aqui está outra abordagem:
fonte
É como o innerText, exceto o padrão. É um pouco mais lento que
removeChild()
, mas é mais fácil de usar e não fará muita diferença de desempenho se você não tiver muitas coisas para excluir.fonte
Em resposta a DanMan, Maarten e Matt. Clonar um nó, para definir o texto, é realmente uma maneira viável nos meus resultados.
Isso também funciona para nós que não estão no dom e retornam nulos ao tentar acessar o parentNode. Além disso, se você precisa estar seguro, um nó está vazio antes de adicionar conteúdo, isso é realmente útil. Considere o caso de uso abaixo.
Acho esse método muito útil ao substituir uma string dentro de um elemento, se você não tiver certeza do que o nó conterá, em vez de se preocupar em limpar a bagunça, comece do zero.
fonte
Aqui está o que eu costumo fazer:
E pronto, mais tarde você pode esvaziar qualquer elemento dom com:
fonte
domEl.innerHTML = ""
é ruim e considerado uma má práticaExistem algumas opções para conseguir isso:
O mais rápido ():
Alternativas (mais lentas):
Referência com as opções sugeridas
fonte
Isso removerá todos os nós dentro do elemento.
fonte
innerText é o vencedor! http://jsperf.com/innerhtml-vs-removechild/133 . Em todos os testes anteriores, o dom interno do nó pai foi excluído na primeira iteração e, em seguida, innerHTML ou removeChild quando aplicado à div vazia.
fonte
innerText
é uma coisa proprietária da MS embora. Apenas dizendo.box
estar disponível não como um var, mas através da pesquisa DOM com base no id, e como owhile
loop faz essa chamada lenta muitas vezes é penalizada.Maneira mais simples de remover os nós filhos de um nó via Javascript
fonte
eu vi pessoas fazendo:
então alguém disse que usar
el.lastNode
é mais rápidono entanto, eu acho que este é o mais rápido:
O que você acha?
ps: este tópico foi um salva-vidas para mim. meu addon firefox foi rejeitado porque eu usei innerHTML. Tem sido um hábito há muito tempo. então eu digo isso. e eu realmente notei uma diferença de velocidade. ao carregar, o innerhtml demorou um pouco para atualizar, porém, passando addElement no seu instante!
fonte
for (var i=0...
embora. Mas aqui é o que eu tenho quando eu corri esses testes: i.imgur.com/Mn61AmI.png também nesses três testes firstNode foi mais rápido do que LastNode e innerHTML que é muito legalUsar um loop de alcance é o mais natural para mim:
De acordo com minhas medidas no Chrome e Firefox, é cerca de 1,3x mais lento. Em circunstâncias normais, isso talvez não importe.
fonte
fonte
Geralmente, o JavaScript usa matrizes para fazer referência a listas de nós DOM. Portanto, isso funcionará bem se você tiver interesse em fazê-lo através da matriz HTMLElements. Além disso, vale a pena notar, porque estou usando uma referência de matriz em vez de proto JavaScript, isso deve funcionar em qualquer navegador, incluindo o IE.
fonte
Por que não estamos seguindo o método mais simples aqui "remova" em loop por dentro enquanto.
fonte
Só vi alguém mencionar essa pergunta em outra e pensei em adicionar um método que ainda não vi:
A função clear está pegando o elemento e usando o nó pai para se substituir por uma cópia sem seus filhos. Não há muito ganho de desempenho se o elemento for escasso, mas quando o elemento possui vários nós, os ganhos de desempenho são realizados.
fonte
Abordagem apenas funcional:
"childNodes" em domChildren fornecerá um nodeList dos elementos filhos imediatos, que fica vazio quando nenhum é encontrado. Para mapear sobre o nodeList, domChildren o converte em matriz. domEmpty mapeia uma função domRemove sobre todos os elementos que a remove.
Exemplo de uso:
remove todos os filhos do elemento body.
fonte
Outras maneiras no jQuery
fonte
.empty()
método, apenas$("#foo").empty()
seria suficientesimplesmente apenas o IE:
true
- significa fazer a remoção profunda - o que significa que todas as crianças também são removidasfonte
O jeito mais fácil:
fonte
container.innerHTML = null
faria o Internet Explorer exibir o textonull
. Então, isso realmente não remove as crianças, eu diria.simples e rápido usando o loop for !!
isso não vai funcionar na
<span>
tag!fonte
<span>
tagSe você quiser colocar algo de volta nisso
div
,innerHTML
provavelmente é melhor.Meu exemplo:
Se eu usar o método
.firstChild
ou.lastChild
, adisplayHTML()
função não funcionará depois, mas não haverá problema com o.innerHTML
método.fonte
Este é um javascript puro, não estou usando jQuery, mas funciona em todos os navegadores, mesmo no IE, e é muito simples de entender
fonte
com jQuery:
fonte
$('#foo').children().remove()
muito mais lógico