Rimuovi tutti gli elementi DOM figlio in div


126

Ho i seguenti codici dojo per creare un elemento grafico di superficie sotto un 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()disegnerà una grafica rettangolo la prima volta. Se chiamo di nuovo questa funzione in un href di ancoraggio come questo:

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

disegna di nuovo un'altra grafica. Quello che mi serve per pulire tutta la grafica sotto il div e poi crearla di nuovo. Come posso aggiungere alcuni codici dojo per farlo?

Risposte:


286
while (node.hasChildNodes()) {
    node.removeChild(node.lastChild);
}

17
Solo per essere pedanti --- la rimozione di nodi DOM senza corrispondenti oggetti JS comporterà perdite di memoria.
Eugene Lazutkin,

2
@Eugene: potresti dire di più al riguardo?
Tom Anderson,

7
@ Tom: dojox.gfx crea oggetti JavaScript per comunicare con il sistema grafico sottostante, che può avere nodi DOM (SVG, VML) o meno (Silverlight, Flash, Canvas). La rimozione di nodi DOM da DOM non rimuove tali oggetti JavaScript e non rimuove nemmeno i nodi DOM perché gli oggetti JavaScript hanno ancora riferimenti a tali nodi DOM. Il modo corretto di gestire questa situazione è descritto nella mia risposta a questa domanda.
Eugene Lazutkin,

3
@robocat Non ha nulla a che fare con IE: gli oggetti JS fanno riferimento agli oggetti DOM mantenendoli in memoria, gli oggetti JS sottostanti vengono mantenuti in memoria dai riferimenti di altri oggetti JS. Ad esempio: una superficie gfx fa riferimento a tutti i suoi figli, un gruppo fa riferimento anche a tutti i suoi figli e così via. L'eliminazione di soli nodi DOM non è sufficiente.
Eugene Lazutkin,

3
@ david-chu-ca - probabilmente la risposta successiva di Eugene (un autore principale della libreria dojo GFX) dovrebbe essere contrassegnata come risposta accettata. Eugene - grazie per il chiarimento.
robocat,

45
node.innerHTML = "";

Non standard, ma veloce e ben supportato.


2
Non supportato in IE. Controlla: theogray.com/blog/2009/06/…
Rajat

4
Sembra essere standard in HTML 5. La voce di blog sopra era un errore dell'utente. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek

Sono abbastanza sicuro che ciò possa causare problemi se i nodi DOM figlio verranno riutilizzati, perché "cancella" (imposta su vuoto) i nodi DOM figlio.
robocat,

Anche per utente stwissel: innerHTML funziona solo se hai a che fare solo con HTML. Se è presente, ad esempio, SVG all'interno, solo la rimozione dell'elemento funzionerà.
robocat,

6
E più lento rispetto alla rimozione dei nodi: jsperf.com/innerhtml-vs-removechild/15
robocat

24

Prima di tutto devi creare una superficie una volta e tenerla a portata di mano. Esempio:

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

domNodeè di solito un disadorno <div>, che viene utilizzato come segnaposto per una superficie.

Puoi cancellare tutto in superficie in una volta (tutti gli oggetti forma esistenti verranno invalidati, non utilizzarli dopo):

surface.clear();

Tutte le funzioni e i metodi relativi alla superficie sono disponibili nella documentazione ufficiale su dojox.gfx.Surface . Esempi di utilizzo sono disponibili in dojox/gfx/tests/.


Potresti aggiungere anche come creare una superficie? Potrebbe non essere chiaro agli utenti pop qui come me :) Grazie
Luca Borrione

20
while(node.firstChild) {
    node.removeChild(node.firstChild);
}

1
jQuery 1.x empty () funziona in questo modo. In jQuery 2.x che supporta solo i browser moderni, empty () usa elem.textContent = ""; comunque solo perché jQuery non significa che non è difettoso, ad esempio stwissel dice "innerHTML funziona solo se hai a che fare solo con HTML. SVG funzionerà solo con la rimozione degli elementi ". Vedere anche altre clausole importanti qui: stackoverflow.com/questions/3955229/...
Robocat

18

In Dojo 1.7 o versioni successive, utilizzare domConstruct.empty(String|DomNode):

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

Nel vecchio Dojo, utilizzare dojo.empty(String|DomNode)(obsoleto in Dojo 1.8):

dojo.empty( id or DOM node );

Ognuno di questi emptymetodi rimuove in modo sicuro tutti i figli del nodo.



2

Se stai cercando un modo moderno> 1.7 Dojo di distruggere tutti i bambini del nodo, questo è il modo:

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

Svuota in sicurezza il contenuto di un elemento DOM. empty () elimina tutti i bambini ma mantiene il nodo lì.

Controlla la documentazione "dom-construct" per maggiori dettagli.

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

Distrugge un elemento DOM. destroy () elimina tutti i bambini e il nodo stesso.


1
Vuole solo che i bambini vengano rimossi, ciò significa domConstruct.empty()che in questo caso sarebbe meglio.
g00glen00b,
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.