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.

+2


a source to share


2 answers


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

.

+4


a source


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.

+1


a source







All Articles