Usuń wszystkie podrzędne elementy DOM z div


126

Mam następujące kody dojo do tworzenia powierzchniowego elementu graficznego pod elementem 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()narysuje grafikę prostokąta za pierwszym razem. Jeśli wywołam tę funkcję ponownie w href kotwicy w ten sposób:

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

ponownie narysuje kolejną grafikę. To, czego potrzebuję, aby wyczyścić całą grafikę pod div, a następnie utworzyć ponownie. Jak mogę dodać kilka kodów dojo, aby to zrobić?

Odpowiedzi:


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

17
Żeby być pedantycznym - usunięcie węzłów DOM bez odpowiadających im obiektów JS doprowadzi do wycieków pamięci.
Eugene Lazutkin,

2
@Eugene: Czy możesz powiedzieć więcej na ten temat?
Tom Anderson

7
@Tom: dojox.gfx tworzy obiekty JavaScript do komunikacji z podstawowym systemem graficznym, który może mieć węzły DOM (SVG, VML) lub nie (Silverlight, Flash, Canvas). Usunięcie węzłów DOM z DOM nie usuwa tych obiektów JavaScript, ani też nie usuwa węzłów DOM, ponieważ obiekty JavaScript nadal mają odniesienia do tych węzłów DOM. Właściwy sposób radzenia sobie z tą sytuacją opisuję w mojej odpowiedzi na to pytanie.
Eugene Lazutkin

3
@robocat Nie ma to nic wspólnego z IE: obiekty JS odwołują się do obiektów DOM, przechowując je w pamięci, podstawowe obiekty JS są przechowywane w pamięci przez odniesienia z innych obiektów JS. Na przykład: powierzchnia gfx odwołuje się do wszystkich swoich elementów podrzędnych, grupa także do wszystkich swoich elementów podrzędnych i tak dalej. Usunięcie samych węzłów DOM nie wystarczy.
Eugene Lazutkin

3
@ david-chu-ca - prawdopodobnie późniejsza odpowiedź Eugene'a (głównego autora biblioteki dojo GFX) powinna być oznaczona jako zaakceptowana odpowiedź. Eugene - dzięki za wyjaśnienie.
robocat

45
node.innerHTML = "";

Niestandardowe, ale szybkie i dobrze obsługiwane.


2
Nieobsługiwane w IE. Sprawdź: theogray.com/blog/2009/06/…
Rajat

4
Wydaje się być standardem w HTML 5. Powyższy wpis na blogu był błędem użytkownika. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek,

Jestem prawie pewien, że może to powodować problemy, jeśli podrzędne węzły DOM będą ponownie używane, ponieważ „czyści” (ustawia puste) podrzędne węzły DOM.
robocat

Również według użytkownika stwissel: innerHTML działa tylko wtedy, gdy masz do czynienia tylko z HTML. Jeśli w środku jest np. SVG, zadziała tylko usunięcie elementu.
robocat

6
I wolniej w porównaniu z usuwaniem węzłów: jsperf.com/innerhtml-vs-removechild/15
robocat

24

Przede wszystkim musisz raz stworzyć powierzchnię i trzymać ją w dogodnym miejscu. Przykład:

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

domNodejest zwykle bez ozdób <div>, które jest używane jako element zastępczy dla powierzchni.

Możesz wyczyścić wszystko na powierzchni za jednym razem (wszystkie istniejące obiekty kształtu zostaną unieważnione, nie używaj ich później):

surface.clear();

Wszystkie funkcje i metody związane z powierzchnią można znaleźć w oficjalnej dokumentacji na dojox.gfx.Surface . Przykłady użycia można znaleźć w dojox/gfx/tests/.


Czy mógłbyś dodać również sposób tworzenia powierzchni? To może nie być jasne dla użytkowników, którzy pojawiają się tutaj, tak jak ja :) Dzięki
Luca Borrione

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

1
W ten sposób działa jQuery 1.x empty (). W jQuery 2.x, który obsługuje tylko nowoczesne przeglądarki, puste () używa elem.textContent = ""; jednak tylko dlatego, że jQuery to robi, nie oznacza, że ​​nie jest błędne, na przykład stwissel mówi, że „innerHTML działa tylko wtedy, gdy masz do czynienia tylko z HTML. SVG tylko wewnątrz Usuwanie elementów będzie działać ”. Zobacz także inne istotne uwagi tutaj: stackoverflow.com/questions/3955229/ ...
robocat

18

W Dojo 1.7 lub nowszym użyj domConstruct.empty(String|DomNode):

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

W starszych Dojo użyj dojo.empty(String|DomNode)(przestarzałe w Dojo 1.8):

dojo.empty( id or DOM node );

Każda z tych emptymetod bezpiecznie usuwa wszystkie elementy podrzędne węzła.



2

Jeśli szukasz nowoczesnego sposobu na zniszczenie wszystkich dzieci węzła> 1.7 Dojo, to jest to sposób:

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

Bezpiecznie opróżnij zawartość elementu DOM. empty () usuwa wszystkie elementy podrzędne, ale zachowuje tam węzeł.

Więcej informacji znajdziesz w dokumentacji „dom-construct”.

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

Niszczy element DOM. Destroy () usuwa wszystkie dzieci i sam węzeł.


1
Chce tylko, aby dzieci zostały usunięte, to znaczy, domConstruct.empty()że w tym przypadku byłoby lepiej.
g00glen00b
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.