2012-06-14 36 views
7

Khi tạo phần tử Hình ảnh mới trong javascript, công cụ bộ nhớ của Google Chrome (Công cụ nhà phát triển> Dòng thời gian> Bộ nhớ) tự động coi nó là một phần tử DOM mới.Vứt bỏ một đối tượng hình ảnh

Trong trường hợp của tôi, tôi kết thúc với hơn 1500 yếu tố DOM và tôi muốn loại bỏ chúng. Tôi đã cố gắng để lưu tất cả các đối tượng trong một mảng và xóa tất cả trong số họ trong một vòng lặp khi tôi đã sẵn sàng tạo mọi đối tượng, dẫn đến các lỗi sau:

Uncaught TypeError: Cannot call method 'removeChild' of null

Đó chỉ ra các đối tượng hình ảnh không xuất hiện trong DOM thực tế.

var images = []; 
var i, image; 

for(i = 0; i < urls.length; i++) { 
    image = new Image(); 
    image.src = urls[i]; 
} 

// other stuff happens 

for(i = 0; i < images.length; i++) { 
    // apparently this doesn't work because I'm not adding the image to my DOM 
    // images[i].parentNode.removeChild(images[i]); 

    // delete images 
} 

Có cách nào để xóa/xóa/bỏ đặt/bỏ đối tượng Hình ảnh không?

Trả lời

9

Thiết images = null sẽ loại bỏ bạn tham khảo trong mã để các đối tượng. Tuy nhiên, để triển khai sự kiện load, Chrome phải có tham chiếu nội bộ riêng cho đối tượng.

Đó là, bạn có thể có mã như thế này:

for(i = 0; i < urls.length; i++) { 
    image = new Image(); 
    image.src = urls[i]; 
    image.onload = function(){alert('Test');}; 
    image = null; 
} 

Bằng cách này bạn vẫn sẽ nhận được rất nhiều cảnh báo "Test", ngay cả khi bạn không có một tham chiếu đến các đối tượng này.

Do đó, đoán là lỗi của Chrome, không phải trong mã của bạn.

Cập nhật: tìm kiếm thông qua các nguồn Chromium loại chứng minh rằng (Ý tôi là những nhận xét về dòng 67-71 của tập tin này, đặc biệt là FIXME lưu ý http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp):

// Make sure the document is added to the DOM Node map. Otherwise, the HTMLImageElement instance 
// may end up being the only node in the map and get garbage-ccollected prematurely. 
// FIXME: The correct way to do this would be to make HTMLImageElement derive from 
// ActiveDOMObject and use its interface to keep its wrapper alive. Then we would 
// remove this code and the special case in isObservableThroughDOM. 
+0

cảm ơn! Tôi biết câu trả lời của bạn là cuối cùng, nhưng bạn đã thực sự thực hiện một số nghiên cứu –

+0

Điều này đã được sửa chữa kể từ khi hoặc đây vẫn là một lỗi? – Hackeron

6

Nếu bạn không thêm chúng vào DOM (như sử dụng appendChild cho cha mẹ), thì removeChild là vô dụng. Các đối tượng Hình ảnh chỉ trong bộ nhớ.

Và để vứt bỏ các mục trong bộ nhớ, bạn chỉ cần loại bỏ các tham chiếu đến các đối tượng này (như đặt biến tham chiếu thành null) và bộ sưu tập rác sẽ thực hiện phần còn lại. Nếu bạn không thể null tất cả, chúng sẽ không được GC'ed.

+0

Câu trả lời hay nhất imo – sidonaldson

+0

Chỉ cần tò mò, nếu bạn không có đối tượng sẽ xóa bộ nhớ được cấp phát từ 'hình ảnh' sau khi được GC? –

1

Tôi nghĩ rằng cách duy nhất là để làm điều này:

for(i = 0; i < images.length; i++) 
    images[i] = null; 
} 

// or just 
images = null; 
2

AFAIK, gán null nên làm sạch nó lên: images[i] = null

2

Để thoát khỏi các lỗi được mô tả bởi "naivists" của chrome và specilly IE và EDGE. Bạn có thể thay đổi nguồn hình ảnh thành trống để không mất bộ nhớ.

image.src = ''; 
image = null; 
Các vấn đề liên quan