Remova todos os elementos DOM filhos em div

126

Eu tenho os seguintes códigos dojo para criar um elemento gráfico de superfície em uma div:

....
<script type=text/javascript>
....
   function drawRec(){
      var node = dojo.byId("surface");
      //   remove all the children graphics
      var surface = dojox.gfx.createSurface(node, 600, 600);

      surface.createLine({
         x1 : 0,
         y1 : 0,
         x2 : 600,
         y2 : 600
      }).setStroke("black");
   }
....
</script>
....
<body>
<div id="surface"></div>
....

drawRec()irá desenhar um retângulo gráfico pela primeira vez. Se eu chamar essa função novamente em uma âncora href assim:

 <a href="javascript:drawRec();">...</a>

desenhará outros gráficos novamente. O que eu preciso para limpar todos os gráficos sob a div e depois criar novamente. Como posso adicionar alguns códigos dojo para fazer isso?

David.Chu.ca
fonte

Respostas:

286
while (node.hasChildNodes()) {
    node.removeChild(node.lastChild);
}
Maurice Perry
fonte
17
Só para ser pedante - remover nós DOM sem objetos JS correspondentes levará a vazamentos de memória.
Eugene Lazutkin
2
@Eugene: Você poderia dizer mais sobre isso?
Tom Anderson
7
@ Tom: dojox.gfx cria objetos JavaScript para se comunicar com o sistema gráfico subjacente, que pode ter nós DOM (SVG, VML) ou não (Silverlight, Flash, Canvas). Remoção de nós DOM de DOM não remove os objetos JavaScript, e não remove nós DOM ou porque objetos JavaScript ainda tem referências a esses nós DOM. A maneira correta de lidar com essa situação está descrita na minha resposta a esta pergunta.
21911 Eugene Lazutkin
3
@robocat Não tem nada a ver com o IE: os objetos JS fazem referência a objetos DOM, mantendo-os na memória, os objetos JS subjacentes são mantidos na memória por referências de outros objetos JS. Por exemplo: uma superfície gfx faz referência a todos os seus filhos, um grupo faz referência a todos os seus filhos também, e assim por diante. Excluir apenas nós DOM não é suficiente.
Eugene Lazutkin
3
@ david-chu-ca - provavelmente a resposta posterior de Eugene (um dos autores principais da biblioteca dojo GFX) deve ser marcada como a resposta aceita. Eugene - obrigado pelo esclarecimento.
robocat
45
node.innerHTML = "";

Não padronizado, mas rápido e bem suportado.

Chetan S
fonte
2
Não suportado no IE. Verifique: theogray.com/blog/2009/06/…
Rajat
4
Parece ser padrão no HTML 5. A entrada do blog acima foi um erro do usuário. developer.mozilla.org/pt-BR/docs/DOM/element.innerHTML
svachalek
Tenho certeza de que isso pode causar problemas se os nós DOM filhos forem reutilizados, porque "limpa" (define como em branco) os nós DOM filhos.
robocat
Também conforme o usuário stwissel: innerHTML só funciona se você estiver lidando apenas com HTML. Se houver, por exemplo, SVG dentro, apenas a remoção do elemento funcionará.
robocat
6
E mais lento em comparação com a remoção de nós: jsperf.com/innerhtml-vs-removechild/15
robocat
24

Primeiro, você precisa criar uma superfície uma vez e mantê-la em algum lugar à mão. Exemplo:

var surface = dojox.gfx.createSurface(domNode, widthInPx, heightInPx);

domNodegeralmente é um sem adornos <div>, usado como espaço reservado para uma superfície.

Você pode limpar tudo na superfície de uma só vez (todos os objetos de forma existentes serão invalidados, não os use depois disso):

surface.clear();

Todas as funções e métodos relacionados à superfície podem ser encontrados na documentação oficial em dojox.gfx.Surface . Exemplos de uso podem ser encontrados em dojox/gfx/tests/.

Eugene Lazutkin
fonte
Você também pode adicionar como criar uma superfície? Pode não ser claro para os usuários pop aqui como me :) Thanks
Luca Borrione
20
while(node.firstChild) {
    node.removeChild(node.firstChild);
}
James
fonte
1
O jQuery 1.x empty () funciona dessa maneira. No jQuery 2.x, que suporta apenas navegadores modernos, o empty () usa, elem.textContent = ""; no entanto, apenas porque o jQuery faz isso não significa que não seja um buggy, por exemplo, stwissel diz que "innerHTML funciona apenas se você estiver lidando apenas com HTML. Se houver, por exemplo, SVG dentro de apenas remoção de elemento funcionará ". Veja também outras notas relevantes aqui: stackoverflow.com/questions/3955229/...
robocat
18

No Dojo 1.7 ou mais recente, use domConstruct.empty(String|DomNode):

require(["dojo/dom-construct"], function(domConstruct){
  // Empty node's children byId:
  domConstruct.empty("someId");
});

No Dojo antigo, use dojo.empty(String|DomNode)(descontinuado no Dojo 1.8):

dojo.empty( id or DOM node );

Cada um desses emptymétodos remove com segurança todos os filhos do nó.

Brian C
fonte
3

Na documentação da API dojo :

dojo.html._emptyNode(node);
Chase Seibert
fonte
2

Se você estiver procurando por uma maneira moderna> Dojo> de destruir todos os filhos de nós, esta é a maneira:

// Destroys all domNode's children nodes
// domNode can be a node or its id:
domConstruct.empty(domNode);

Esvazie com segurança o conteúdo de um elemento DOM. empty () exclui todos os filhos, mas mantém o nó lá.

Verifique a documentação "dom-construct" para mais detalhes.

// Destroys domNode and all it's children
domConstruct.destroy(domNode);

Destrói um elemento DOM. destroy () exclui todos os filhos e o próprio nó.

Rui Marques
fonte
1
Ele só quer que as crianças sejam removidas, o que significa que domConstruct.empty()seria melhor neste caso.
G00glen00b