It seems that in Javascript, if you have a reference to some DOM element, and then modify the DOM by adding additional elements to document.body, your DOM reference becomes invalidated.
Consider the following code:
<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>
When you click on the DIV, this alerts "true", and then "false." So in other words, after modifying document.body
, the reference to the DIV element is no longer valid. This behavior is the same on Firefox and MSIE.
Some questions:
Why does this 开发者_StackOverflow社区occur? Is this behavior specified by the ECMAScript standard, or is this a browser-specific issue?
Note: there's another question posted on stackoverflow that seems to be referring to the same issue, but neither the question nor the answers are very clear.
When you append to document.body.innerHTML
, that's equivalent to
document.body.innerHTML = document.body.innerHTML + "<div>blah blah</div>";
When you assign to innerHTML
like that the browser has to reparse and therefore recreate that part of the DOM. The div element in foo
is still valid, but it's not a part of the document anymore. Then, of course, when you call document.getElementById
it gets the new div that replaced foo
.
The behavior DOM specific, so it's not defined in the ECMAScript standard. It's not defined in any current W3C standard, since innerHTML
was originally a non-standard property, but it is finally standardized in HTML5.
The solution is to either call document.getElementById
to get the reference back, or use document.createElement
, <element>.appendChild
, etc. instead of setting innerHTML
.
The reference won't be valid again until the function ends and the DOM refreshes and all the innerHTML is actually converted. Try calling the function again using setInterval
and you will see the first alert being true again.
Edit: I just noticed that your HTML string doesn't have an id="foo" in it. Put that in it and try again.
精彩评论