Javascript:“悬空”参考DOM元素?

时间:2010-04-30 23:51:32

标签: javascript dom

似乎在Javascript中,如果你有一些DOM元素的引用,然后通过向document.body添加其他元素来修改DOM,那么你的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时,会发出“true”警告,然后“false”。换句话说,在修改document.body之后,对DIV元素的引用不再有效。这种行为在Firefox和MSIE上是相同的。

有些问题:

为什么会这样? 此行为是由ECMAScript标准指定的,还是特定于浏览器的问题?

注意:stackoverflow上发布的another question似乎是指同一个问题,但问题和答案都不是很清楚。

2 个答案:

答案 0 :(得分:5)

当您追加到document.body.innerHTML时,这相当于

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

当您分配给innerHTML时,浏览器必须重新分析并因此重新创建DOM的那部分。 foo中的div元素仍然是有效,但它不再是文档的一部分。然后,当然,当您致电document.getElementById时,它会获得替换foo的新div。

行为DOM特定,因此未在ECMAScript标准中定义。它没有在任何当前的W3C标准中定义,因为innerHTML最初是非标准属性,但它最终在HTML5中标准化。

解决方案是致电document.getElementById以获取参考,或使用document.createElement<element>.appendChild等,而不是设置innerHTML

答案 1 :(得分:1)

在函数结束并且DOM刷新并且实际转换了所有innerHTML之前,引用将无法再次有效。尝试使用setInterval再次调用该函数,您将看到第一个警报再次为真。

编辑:我刚注意到你的HTML字符串中没有id =“foo”。把它放进去再试一次。