2011-09-25 71 views
1

我使用document.createElement創建了許多新的頁面元素(在某些任意層次結構中),並一直使用element.removeChild()擦除我不再需要的元素。我想知道這是否會正確清理所有的子元素,或者如果我應該使用某種遞歸函數。 JavaScript使用垃圾回收器,所以我不需要擔心這個,對吧?是removeChild遞歸?

+0

不,你不應該,除非你使用蹩腳的瀏覽器:-) IE的任何人? – Bojangles

+0

好的。是否還有其他更合適的功能可以用來從DOM中刪除整個節點? –

+0

同樣,沒有''element.removeChild()'是好的,除非你使用jQuery或其他庫,但它們只包裝原生JavaScript函數。 – Bojangles

回答

2

使用element.removeChild(childElement)從您的文檔樹中刪除節點。但是,如果您有元素的引用,則元素將被垃圾回收(GC)而不是

考慮:
實施例1(可怕實踐):

<body><script> 
var d = document.createElement("div"); 
document.body.appendChild(d); 
document.body.removeChild(d); 
//The global scope won't disappear. Therefore, the variable d will stay, 
// which is a reference to DIV --> The DIV element won't be GC-ed 
</script></body> 

實施例2(不好的做法):

function foo(){ 
    var s = document.createElement("span"); 
    document.body.appendChild(s); 
    s.innerHTML = "This could be a huge tree."; 
    document.body.addEventListener("click", function(ev){ 
     alert(eval(prompt("s will still refer to the element:", "s"))); 
     //Use the provided eval to see that s and s.innerHTML still exist 
     // Because this event listener is added in the same scope as where 
     // DIV `d` is created. 
    }, true); 
    document.body.removeChild(s); 
} 
foo(); 

實施例3(好的做法) :

function main(){ 
    //Functions defined below 
    addDOM(); 
    addEvent(); 
    remove(); 
    //Zero variables have been leaked to this scope. 

    function addDOM(){ 
     var d = document.createElement("div"); 
     d.id = "doc-rob"; 
     document.body.appendChild(d); 
    } 
    function addEvent(){ 
     var e = document.getElementById("doc-rob"); 
     document.body.addEventListener("click", function(ev){ 
      e && alert(e.tagName); 
      //Displays alert("DIV") if the element exists, else: nothing happens. 
     }); 
    } 
    function remove(){ 
     var f = document.getElementById("doc-rob"); 
     f.parentNode.removeChild(f); 
     alert(f);//f is still defined in this scope 
     Function("alert('Typeof f = ' + typeof f);")(); //alert("Typeof f = undefined") 
    } 
} 
main(); 
+1

很好的答案。關於你的第二個例子,大多數(如果不是全部的話)現代JavaScript引擎有非常優化的GC,並且你認爲元素不是GC的原因正是因爲你把'eval'放在那裏!即如果用大對象運行代碼並刪除'eval'語句並強制GC(例如在shell中),則可以看到它們實際上已經清理乾淨,因爲它們可以執行靜態引用檢查並得出結論:不再存在需要持有這些對象,即使傳統的詞彙範圍界定爲範圍鏈的一部分。 – davin

+0

我說的是,在大多數現代瀏覽器中,第二個例子根本沒有問題(假設你拿出'eval')。 – davin