Javascript: "Dangling" DOM element reference?
It seems that in Javascript, if you have a reference to some DOM element and then change the DOM by adding additional elements to the document.body, your DOM reference will become invalid.
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 it warns "true" and then "false". In other words, after the change, the document.body
reference to the DIV element is no longer valid. This behavior is the same for Firefox and MSIE.
Some questions:
Why is this happening? Is this behavior the specified ECMAScript standard, or is it a browser issue?
Note: There 's another question posted on stackoverflow that seems to be about the same issue, but neither the question nor the answers are very clear.
a source to share
When you add to document.body.innerHTML
, which is equivalent to
document.body.innerHTML = document.body.innerHTML + "<div>blah blah</div>";
When you assign innerHTML
it like this, the browser must revise and therefore recreate that part of the DOM. The div foo
remains in effect, but is no longer part of the document. Then of course when you call document.getElementById
it gets the new div it replaced foo
.
DOM behavior is specific, so it is not defined in the ECMAScript standard. It is not defined in any current W3C standard as innerHTML
it was originally a non-standard property, but it is finally standardized in HTML5.
The solution is to either call document.getElementById
to return the link, or use document.createElement
, <element>.appendChild
etc. instead of installing innerHTML
.
a source to share
The link will not be valid again until the function ends and the DOM is updated and all innerHTML is actually converted. Try calling the function again using setInterval
and you will see the first warning again.
Edit: I just noticed that your HTML string does not contain id = "foo". Put this in it and try again.
a source to share