ลบองค์ประกอบ DOM ลูกทั้งหมดใน div


126

ฉันมีรหัส dojo ต่อไปนี้เพื่อสร้างองค์ประกอบกราฟิกพื้นผิวภายใต้ 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()จะวาดกราฟิกสี่เหลี่ยมผืนผ้าในครั้งแรก ถ้าฉันเรียกใช้ฟังก์ชันนี้อีกครั้งใน anchor href เช่นนี้:

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

มันจะวาดกราฟิกอื่นอีกครั้ง สิ่งที่ฉันต้องการในการล้างกราฟิกทั้งหมดภายใต้ div แล้วสร้างอีกครั้ง ฉันจะเพิ่มรหัส dojo เพื่อทำสิ่งนั้นได้อย่างไร

คำตอบ:


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

17
เพื่อเป็นการอวดดี --- การลบโหนด DOM โดยไม่มีวัตถุ JS ที่เกี่ยวข้องจะนำไปสู่การรั่วไหลของหน่วยความจำ
Eugene Lazutkin

2
@ ยูจีน: คุณช่วยพูดเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ไหม?
Tom Anderson

7
@Tom: dojox.gfx สร้างออบเจ็กต์ JavaScript เพื่อสื่อสารกับระบบกราฟิกพื้นฐานซึ่งอาจมีโหนด DOM (SVG, VML) หรือไม่ก็ได้ (Silverlight, Flash, Canvas) การลบโหนด DOM ออกจาก DOM ไม่ได้เป็นการลบอ็อบเจ็กต์ JavaScript เหล่านั้นและไม่ได้ลบโหนด DOM เนื่องจากอ็อบเจ็กต์ JavaScript ยังคงมีการอ้างอิงถึงโหนด DOM เหล่านั้น วิธีที่ถูกต้องในการจัดการสถานการณ์นี้มีอธิบายไว้ในคำตอบของฉันสำหรับคำถามนี้
Eugene Lazutkin

3
@robocat ไม่มีส่วนเกี่ยวข้องกับ IE: วัตถุ JS อ้างอิงวัตถุ DOM ซึ่งเก็บไว้ในหน่วยความจำวัตถุ JS ที่อยู่ภายใต้จะถูกเก็บไว้ในหน่วยความจำโดยการอ้างอิงจากวัตถุ JS อื่น ๆ ตัวอย่างเช่นพื้นผิว gfx อ้างอิงลูก ๆ ทั้งหมดกลุ่มอ้างอิงลูกทั้งหมดด้วยและอื่น ๆ การลบแค่โหนด DOM นั้นไม่เพียงพอ
Eugene Lazutkin

3
@ david-chu-ca - อาจเป็นคำตอบในภายหลังโดย Eugene (ผู้เขียนหลักของห้องสมุด dojo 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/.


คุณช่วยเพิ่มวิธีสร้างพื้นผิวได้ไหม อาจไม่ชัดเจนสำหรับผู้ใช้ที่มาที่นี่เหมือนฉัน :) ขอบคุณ
Luca Borrione

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

1
jQuery 1.x empty () ทำงานในลักษณะนั้น ใน jQuery 2.x ซึ่งรองรับเฉพาะเบราว์เซอร์สมัยใหม่เท่านั้น empty () จะใช้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 รุ่นเก่าให้ใช้dojo.empty(String|DomNode)(เลิกใช้งานที่ Dojo 1.8):

dojo.empty( id or DOM node );

แต่ละemptyวิธีเหล่านี้จะลบลูกทั้งหมดของโหนดอย่างปลอดภัย



2

หากคุณกำลังมองหาวิธี Dojo ที่ทันสมัย> 1.7 ในการทำลายลูก ๆ ของโหนดทั้งหมดนี่คือวิธี:

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

ล้างเนื้อหาขององค์ประกอบ DOM อย่างปลอดภัย empty () ลบชายด์ทั้งหมด แต่เก็บโหนดไว้ที่นั่น

ตรวจสอบเอกสาร "dom-construction" สำหรับรายละเอียดเพิ่มเติม

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

ทำลายองค์ประกอบ DOM ทำลาย () ลบเด็กทั้งหมดและโหนดเอง


1
เขาต้องการให้เอาเด็กออกเท่านั้นนั่นหมายความว่าdomConstruct.empty()จะดีกว่าในกรณีนี้
g00glen00b
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.