Видаліть усі дочірні елементи DOM у розділі


126

У мене є такі коди доджо, щоб створити поверхневий графічний елемент під ділом:

....
<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()малюватиме графіку прямокутника вперше. Якщо я знову закликаю цю функцію в href-якорі на зразок цього:

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

вона знову намалює ще одну графіку. Що мені потрібно, щоб очистити всю графіку під дією, а потім створити заново. Як я можу додати кілька доджо-кодів для цього?

Відповіді:


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

17
Просто бути педантичним --- видалення DOM-вузлів без відповідних JS-об'єктів призведе до витоку пам'яті.
Євген Лазуткін

2
@Eugene: Не могли б ви сказати більше про це?
Том Андерсон

7
@Tom: dojox.gfx створює об’єкти JavaScript для зв'язку з базовою графічною системою, яка може мати вузли DOM (SVG, VML) чи ні (Silverlight, Flash, Canvas). Видалення DOM-вузлів з DOM не видаляє ці об’єкти JavaScript, а також не видаляє DOM-вузли, оскільки об’єкти JavaScript досі мають посилання на ці вузли DOM. Правильний спосіб вирішення цієї ситуації описаний у моїй відповіді на це питання.
Євген Лазуткін

3
@robocat Це не має нічого спільного з IE: JS-об'єкти посилаються на DOM-об'єкти, що зберігають їх у пам'яті, а основні JS-об'єкти зберігаються в пам'яті за посиланнями інших JS-об'єктів. Наприклад: поверхня gfx посилається на всіх своїх дітей, група також посилається на всіх своїх дітей тощо. Видалення лише вузлів DOM недостатньо.
Євген Лазуткін

3
@ david-chu-ca - ймовірно, пізніша відповідь Євгена (основного автора бібліотеки доджо GFX) повинна бути позначена як прийнята відповідь. Євген - дякую за роз’яснення.
robocat

45
node.innerHTML = "";

Нестандартний, але швидкий і добре підтримуваний.


2
Не підтримується в IE. Перевірка: theogray.com/blog/2009/06/…
Раджат

4
Здається, що це стандарт у HTML 5. Вищенаведений запис у блозі був помилкою користувача. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek

Я впевнений, що це може спричинити проблеми, якщо дочірні вузли DOM будуть повторно використані, оскільки він "очищає" (встановлює порожнє) дочірніх DOM-вузлів.
robocat

Також відповідно до користувача stwissel: innerHTML працює лише у тому випадку, якщо ви маєте справу лише з HTML. Якщо є, наприклад, SVG всередині, лише видалення елемента буде працювати.
robocat

6
І повільніше порівняно з видаленням вузлів: jsperf.com/innerhtml-vs-removechild/15
robocat

24

Перш за все вам потрібно створити поверхню один раз і тримати її десь під рукою. Приклад:

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

domNode зазвичай неприхований <div> , який використовується як заповнювач для поверхні.

Ви можете очистити все на поверхні за один раз (всі існуючі об'єкти фігури будуть визнані недійсними, після цього не використовуйте їх):

surface.clear();

Всі функції та методи, пов'язані з поверхнею, можна знайти в офіційній документації на dojox.gfx.Surface . Приклади використання можна знайти в dojox/gfx/tests/.


Не могли б ви також додати, як створити поверхню? Користувачам це може бути не зрозуміло, як сюди потрапляють такі, як я :) Спасибі
Лука Borrione

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

1
jQuery 1.x empty () працює таким чином. У jQuery 2.x, який підтримує лише сучасні браузери, порожній () використовує, elem.textContent = ""; однак, тільки тому, що jQuery не означає, що він не баггі, наприклад, stwissel каже: "innerHTML працює лише у тому випадку, якщо ви маєте справу лише з HTML. Якщо є напр. SVG все лише для видалення елемента буде працювати ". Дивіться також інші відповідні примітки тут: stackoverflow.com/questions/3955229 / ...
robocat

18

У Dojo 1.7 або новіших версіях використовуйте domConstruct.empty(String|DomNode):

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

У старшому доджо використовуйте dojo.empty(String|DomNode)(застаріле в Dojo 1.8):

dojo.empty( id or DOM node );

Кожен з цих emptyметодів безпечно видаляє всіх дітей вузла.



2

Якщо ви шукаєте сучасний спосіб> 1.7 доджо знищити всіх дітей вузла, це такий спосіб:

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

Безпечно спорожніть вміст елемента DOM. empty () видаляє всіх дітей, але зберігає вузол там.

Щоб отримати детальнішу інформацію, перегляньте документацію "dom-construct".

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

Знищує елемент DOM. знищити () видаляє всіх дітей і сам вузол.


1
Він лише хоче, щоб дітей віддалили, це означає, domConstruct.empty()що в цьому випадку буде краще.
g00glen00b
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.