Eliminar todos los elementos DOM secundarios en div

126

Tengo los siguientes códigos de dojo para crear un elemento gráfico de superficie bajo 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()dibujará un rectángulo de gráficos por primera vez. Si vuelvo a llamar a esta función en un ancla href como esta:

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

dibujará otros gráficos nuevamente. Lo que necesito para limpiar todos los gráficos debajo del div y luego crear de nuevo. ¿Cómo puedo agregar algunos códigos dojo para hacer eso?

David.Chu.ca
fuente

Respuestas:

286
while (node.hasChildNodes()) {
    node.removeChild(node.lastChild);
}
Maurice Perry
fuente
17
Solo para ser pedante: eliminar nodos DOM sin los objetos JS correspondientes provocará pérdidas de memoria.
Eugene Lazutkin
2
@ Eugene: ¿Podría decir más sobre eso?
Tom Anderson el
77
@Tom: dojox.gfx crea objetos JavaScript para comunicarse con el sistema gráfico subyacente, que puede tener nodos DOM (SVG, VML) o no (Silverlight, Flash, Canvas). La eliminación de nodos DOM del DOM no elimina esos objetos JavaScript, y tampoco elimina los nodos DOM porque los objetos JavaScript todavía tienen referencias a esos nodos DOM. La forma correcta de manejar esta situación se describe en mi respuesta a esta pregunta.
Eugene Lazutkin
3
@robocat No tiene nada que ver con IE: los objetos JS hacen referencia a objetos DOM que los mantienen en memoria, los objetos JS subyacentes se mantienen en memoria por referencias de otros objetos JS. Por ejemplo: una superficie gfx hace referencia a todos sus elementos secundarios, un grupo también hace referencia a todos sus elementos secundarios, y así sucesivamente. Eliminar solo nodos DOM no es suficiente.
Eugene Lazutkin
3
@ david-chu-ca: probablemente la respuesta posterior de Eugene (autor principal de la biblioteca dojo GFX) debe marcarse como la respuesta aceptada. Eugene: gracias por la aclaración.
robocat
45
node.innerHTML = "";

No estándar, pero rápido y bien soportado.

Chetan S
fuente
2
No es compatible con IE. Compruebe: theogray.com/blog/2009/06/…
Rajat
44
Parece ser estándar en HTML 5. La entrada de blog anterior fue un error del usuario. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek
Estoy bastante seguro de que esto puede causar problemas si los nodos DOM secundarios se van a reutilizar, porque "borra" (se pone en blanco) los nodos DOM secundarios.
robocat el
También según el usuario stwissel: innerHTML solo funciona si solo se trata de HTML. Si hay, por ejemplo, SVG dentro, solo funcionará la eliminación de elementos.
robocat el
66
Y más lento en comparación con la eliminación de nodos: jsperf.com/innerhtml-vs-removechild/15
robocat
24

En primer lugar, debe crear una superficie una vez y tenerla a mano. Ejemplo:

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

domNodees generalmente un sin adornos <div>, que se utiliza como marcador de posición para una superficie.

Puede borrar todo en la superficie de una vez (todos los objetos de forma existentes se invalidarán, no los use después de eso):

surface.clear();

Todas las funciones y métodos relacionados con la superficie se pueden encontrar en la documentación oficial en dojox.gfx.Surface . Se pueden encontrar ejemplos de uso en dojox/gfx/tests/.

Eugene Lazutkin
fuente
¿Podría agregar también cómo crear una superficie? Puede que no esté claro para los usuarios que
aparecen
20
while(node.firstChild) {
    node.removeChild(node.firstChild);
}
James
fuente
1
jQuery 1.x empty () funciona de esa manera. En jQuery 2.x, que solo es compatible con los navegadores modernos, empty () usa elem.textContent = ""; sin embargo solo porque jQuery lo hace, no significa que no tenga errores, por ejemplo, stwissel dice "innerHTML solo funciona si solo se trata de HTML. Si hay SVG dentro de solo la eliminación de elementos funcionará ". Consulte también otras notas relevantes aquí: stackoverflow.com/questions/3955229/…
robocat el
18

En Dojo 1.7 o posterior, use domConstruct.empty(String|DomNode):

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

En Dojo anterior, use dojo.empty(String|DomNode)(en desuso en Dojo 1.8):

dojo.empty( id or DOM node );

Cada uno de estos emptymétodos elimina de forma segura a todos los hijos del nodo.

Brian C
fuente
2

Si está buscando una forma moderna> 1.7 Dojo de destruir a todos los hijos del nodo, esta es la forma:

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

Vacíe de forma segura el contenido de un elemento DOM. empty () elimina todos los elementos secundarios pero mantiene el nodo allí.

Consulte la documentación de "dom-construct" para obtener más detalles.

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

Destruye un elemento DOM. destroy () elimina todos los hijos y el nodo en sí.

Rui Marques
fuente
1
Él solo quiere que los niños sean retirados, eso significa domConstruct.empty()que sería mejor en este caso.
g00glen00b