Xóa tất cả các phần tử DOM con trong div


126

Tôi có các mã võ đường sau để tạo thành phần đồ họa bề mặt theo 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()sẽ vẽ đồ họa hình chữ nhật lần đầu tiên. Nếu tôi gọi hàm này một lần nữa trong một neo href như thế này:

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

nó sẽ vẽ một đồ họa khác một lần nữa. Những gì tôi cần để làm sạch tất cả các đồ họa theo div và sau đó tạo lại. Làm thế nào tôi có thể thêm một số mã dojo để làm điều đó?

Câu trả lời:


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

17
Chỉ cần là phạm vi --- loại bỏ các nút DOM mà không có các đối tượng JS tương ứng sẽ dẫn đến rò rỉ bộ nhớ.
Eugene Lazutkin

2
@Eugene: Bạn có thể nói thêm về điều đó?
Tom Anderson

7
@Tom: dojox.gfx tạo các đối tượng JavaScript để giao tiếp với hệ thống đồ họa bên dưới, có thể có các nút DOM (SVG, VML) hoặc không (Silverlight, Flash, Canvas). Việc xóa các nút DOM khỏi DOM không xóa các đối tượng JavaScript đó và nó cũng không xóa các nút DOM vì các đối tượng JavaScript vẫn có các tham chiếu đến các nút DOM đó. Cách chính xác để xử lý tình huống này được mô tả trong câu trả lời của tôi cho câu hỏi này.
Eugene Lazutkin

3
@robocat Không liên quan gì đến IE: Các đối tượng JS tham chiếu các đối tượng DOM giữ chúng trong bộ nhớ, các đối tượng JS nằm bên dưới được giữ trong bộ nhớ bởi các tham chiếu từ các đối tượng JS khác. Ví dụ: một bề mặt gfx tham chiếu tất cả các phần tử con của nó, một nhóm cũng tham chiếu tất cả các phần tử con của nó, v.v. Chỉ xóa các nút DOM là không đủ.
Eugene Lazutkin

3
@ david-chu-ca - có lẽ là câu trả lời sau của Eugene (một tác giả chính của thư viện Gjo dojo) nên được đánh dấu là câu trả lời được chấp nhận. Eugene - cảm ơn đã làm rõ.
robocat

45
node.innerHTML = "";

Không chuẩn, nhưng nhanh và được hỗ trợ tốt.


2
Không được hỗ trợ trong IE. Kiểm tra: theogray.com/blog/2009/06/ trên
Rajat

4
Có vẻ là tiêu chuẩn trong HTML 5. Mục blog trên là lỗi người dùng. developer.mozilla.org/en-US/docs/DOM/element.innerHTML
svachalek

Tôi khá chắc chắn rằng điều này có thể gây ra vấn đề nếu các nút DOM con sẽ được sử dụng lại, bởi vì nó "xóa" (đặt thành trống) các nút DOM con.
robocat

Ngoài ra, theo người dùng stwissel: InternalHTML chỉ hoạt động nếu bạn chỉ giao dịch với HTML. Nếu có ví dụ SVG bên trong chỉ phần tử loại bỏ sẽ hoạt động.
robocat

6
chậm hơn so với loại bỏ nút: jsperf.com/innerhtml-vs-removechild/15
robocat

24

Trước hết bạn cần tạo một bề mặt một lần và giữ nó ở đâu đó tiện dụng. Thí dụ:

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

domNodethường không được trang bị <div>, được sử dụng như một trình giữ chỗ cho một bề mặt.

Bạn có thể xóa mọi thứ trên bề mặt trong một lần (tất cả các đối tượng hình dạng hiện tại sẽ bị vô hiệu, không sử dụng chúng sau đó):

surface.clear();

Tất cả các chức năng và phương pháp liên quan đến bề mặt có thể được tìm thấy trong tài liệu chính thức trên dojox.gfx.Surface . Ví dụ về việc sử dụng có thể được tìm thấy trong dojox/gfx/tests/.


Bạn có thể vui lòng thêm cách tạo bề mặt không? Người dùng có thể không rõ ràng ở đây như tôi :) Cảm ơn
Luca Borrione

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

1
jQuery 1.x blank () hoạt động theo cách đó. Trong jQuery 2.x chỉ hỗ trợ các trình duyệt hiện đại, elem.textContent = ""; tuy nhiên, sử dụng rỗng () chỉ vì jQuery không có nghĩa là nó không có lỗi, ví dụ như stwissel nói "InternalHTML chỉ hoạt động nếu bạn chỉ giao dịch với HTML. Nếu có SVG bên trong chỉ loại bỏ phần tử sẽ hoạt động ". Ngoài ra, hãy xem các ghi chú có liên quan khác tại đây: stackoverflow.com/questions/3955229/ từ
robocat

18

Trong Dojo 1.7 trở lên, sử dụng domConstruct.empty(String|DomNode):

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

Trong Dojo cũ hơn, sử dụng dojo.empty(String|DomNode)(không dùng ở Dojo 1.8):

dojo.empty( id or DOM node );

Mỗi emptyphương thức này loại bỏ một cách an toàn tất cả các con của nút.



2

Nếu bạn đang tìm kiếm một cách hiện đại> 1.7 Dojo để tiêu diệt tất cả các con của nút thì đây là cách:

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

Làm trống an toàn các nội dung của một phần tử DOM. trống () xóa tất cả trẻ em nhưng giữ nút ở đó.

Kiểm tra tài liệu "dom-construc" để biết thêm chi tiết.

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

Phá hủy một phần tử DOM. phá hủy () xóa tất cả trẻ em và nút chính nó.


1
Anh ta chỉ muốn những đứa trẻ được gỡ bỏ, điều đó có nghĩa là domConstruct.empty()sẽ tốt hơn trong trường hợp này.
g00glen00b
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.