Entfernen Sie alle untergeordneten DOM-Elemente in div

126

Ich habe die folgenden Dojo-Codes, um ein Oberflächengrafikelement unter einem div zu erstellen:

....
<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()zeichnet beim ersten Mal eine Rechteckgrafik. Wenn ich diese Funktion in einem Anker href wie folgt erneut aufrufe:

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

es wird wieder eine andere Grafik gezeichnet. Was ich brauche, um alle Grafiken unter dem div zu bereinigen und dann neu zu erstellen. Wie kann ich dazu einige Dojo-Codes hinzufügen?

David.Chu.ca
quelle

Antworten:

286
while (node.hasChildNodes()) {
    node.removeChild(node.lastChild);
}
Maurice Perry
quelle
17
Nur um pedantisch zu sein - das Entfernen von DOM-Knoten ohne entsprechende JS-Objekte führt zu Speicherlecks.
Eugene Lazutkin
2
@ Eugene: Kannst du mehr dazu sagen?
Tom Anderson
7
@Tom: dojox.gfx erstellt JavaScript-Objekte für die Kommunikation mit dem zugrunde liegenden Grafiksystem, die möglicherweise DOM-Knoten (SVG, VML) haben oder nicht (Silverlight, Flash, Canvas). Durch das Entfernen von DOM-Knoten aus DOM werden diese JavaScript-Objekte nicht entfernt, und DOM-Knoten werden auch nicht entfernt , da JavaScript-Objekte weiterhin Verweise auf diese DOM-Knoten haben. Der richtige Umgang mit dieser Situation ist in meiner Antwort auf diese Frage beschrieben.
Eugene Lazutkin
3
@robocat Es hat nichts mit IE zu tun: JS-Objekte verweisen auf DOM-Objekte, die sie im Speicher behalten, zugrunde liegende JS-Objekte werden durch Verweise von anderen JS-Objekten im Speicher gehalten. Beispiel: Eine gfx-Oberfläche verweist auf alle untergeordneten Elemente, eine Gruppe verweist auch auf alle untergeordneten Elemente usw. Es reicht nicht aus, nur DOM-Knoten zu löschen.
Eugene Lazutkin
3
@ david-chu-ca - wahrscheinlich sollte die spätere Antwort von Eugene (einem Hauptautor der Dojo-GFX-Bibliothek) als akzeptierte Antwort markiert werden. Eugene - danke für die Klarstellung.
Robocat
45
node.innerHTML = "";

Nicht standardisiert, aber schnell und gut unterstützt.

Chetan S.
quelle
2
Wird im IE nicht unterstützt. Überprüfen Sie: theogray.com/blog/2009/06/…
Rajat
4
Scheint in HTML 5 Standard zu sein. Der obige Blogeintrag war ein Benutzerfehler. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek
Ich bin mir ziemlich sicher, dass dies zu Problemen führen kann, wenn die untergeordneten DOM-Knoten wiederverwendet werden, da die untergeordneten DOM-Knoten "gelöscht" (auf "leer" gesetzt) ​​werden.
Robocat
Auch laut Benutzer stwissel: innerHTML funktioniert nur, wenn Sie sich nur mit HTML beschäftigen. Wenn zB nur SVG enthalten ist, funktioniert das Entfernen von Elementen.
Robocat
6
Und langsamer im Vergleich zum Entfernen von Knoten: jsperf.com/innerhtml-vs-removechild/15
Robocat
24

Zunächst müssen Sie eine Oberfläche einmal erstellen und an einem handlichen Ort aufbewahren. Beispiel:

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

domNodeist in der Regel ein schmuckloser <div>, der als Platzhalter für eine Oberfläche verwendet wird.

Sie können alles auf der Oberfläche auf einmal löschen (alle vorhandenen Formobjekte werden ungültig, verwenden Sie sie danach nicht mehr):

surface.clear();

Alle oberflächenbezogenen Funktionen und Methoden finden Sie in der offiziellen Dokumentation unter dojox.gfx.Surface . Anwendungsbeispiele finden Sie in dojox/gfx/tests/.

Eugene Lazutkin
quelle
Könnten Sie bitte auch hinzufügen, wie eine Oberfläche erstellt wird? Es könnte nicht klar sein, dass Benutzer wie ich hierher kommen :) Danke
Luca Borrione
20
while(node.firstChild) {
    node.removeChild(node.firstChild);
}
James
quelle
1
jQuery 1.x empty () funktioniert so. In jQuery 2.x, das nur moderne Browser unterstützt, verwendet empty () elem.textContent = ""; jedoch nur, weil jQuery dies tut, heißt das nicht, dass es nicht fehlerhaft ist. Stwissel sagt beispielsweise: "innerHTML funktioniert nur, wenn Sie nur mit HTML arbeiten. Wenn es z SVG nur innerhalb der Elemententfernung funktioniert ". Siehe auch andere relevante Hinweise hier: stackoverflow.com/questions/3955229/…
Robocat
18

Verwenden Sie in Dojo 1.7 oder neuer domConstruct.empty(String|DomNode):

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

Verwenden Sie im älteren Dojo dojo.empty(String|DomNode)(veraltet bei Dojo 1.8):

dojo.empty( id or DOM node );

Jede dieser emptyMethoden entfernt sicher alle untergeordneten Elemente des Knotens.

Brian C.
quelle
3

Aus der Dojo-API- Dokumentation :

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

Wenn Sie nach einer modernen> 1.7 Dojo-Methode suchen, um alle Kinder des Knotens zu zerstören, ist dies die folgende Methode:

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

Leeren Sie den Inhalt eines DOM-Elements sicher. empty () löscht alle untergeordneten Elemente, behält jedoch den Knoten dort bei.

Weitere Informationen finden Sie in der Dokumentation zu "dom-construct".

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

Zerstört ein DOM-Element. destroy () löscht alle untergeordneten Elemente und den Knoten selbst.

Rui Marques
quelle
1
Er möchte nur, dass die Kinder entfernt werden, das heißt domConstruct.empty(), in diesem Fall wäre es besser.
g00glen00b