2010-04-30 93 views
2

似乎在Javascript中,如果您有一個DOM元素的引用,然後通過向document.body添加其他元素來修改DOM,那麼您的DOM引用將失效。Javascript:「Dangling」引用DOM元素?

考慮下面的代碼:

<html> 
<head> 
<script type = "text/javascript"> 
function work() 
{ 
var foo = document.getElementById("foo"); 
alert(foo == document.getElementById("foo")); 

document.body.innerHTML += "<div>blah blah</div>"; 
alert(foo == document.getElementById("foo")); 
} 

</script> 
</head> 

<body> 
<div id = "foo" onclick='work()'>Foo</div> 
</body> 
</html> 

當您點擊DIV,這提醒 「真」,然後是 「假的」。換句話說,修改document.body後,對DIV元素的引用不再有效。在Firefox和MSIE上這種行爲是相同的。

一些問題:

爲什麼會發生這種情況? 此行爲是由ECMAScript標準指定的,還是這是一個特定於瀏覽器的問題?

注意:有another question張貼在似乎是指同一問題的計算器,但問題和答案都不是很清楚。

回答

4

當你追加到document.body.innerHTML,當你分配給innerHTML這樣的瀏覽器必須重新分析,並因此重新創建DOM的部分是相當於

document.body.innerHTML = document.body.innerHTML + "<div>blah blah</div>"; 

foo中的div元素仍然是有效的,但它不再是文檔的一部分。那麼,當然,當你撥打document.getElementById時,它會得到新的div,代替foo

行爲DOM特定,所以它沒有在ECMAScript標準中定義。它沒有在當前的W3C標準中定義,因爲innerHTML最初是一個非標準屬性,但它最終在HTML5中被標準化。

的解決方法是調用document.getElementById來獲取基準回來,或者使用的document.createElement<element>.appendChild等,而不是設置innerHTML

+0

'innerHTML'實際上是在HTML5中標準化的。 – 2010-05-01 13:38:27

1

該引用在函數結束並且DOM刷新並且實際轉換了所有innerHTML之前不會再生效。嘗試使用setInterval再次調用該函數,您將看到第一個警報再次爲真。

編輯:我只注意到你的HTML字符串中沒有id =「foo」。把它放在裏面,然後再試一次。