I write the following JS and run in IE 10:
function test() {
var nodes = document.getElementsByTagName("h1");
document.writeln(nodes.length);
for (var j = 0; j < nodes.length; j++) { <=== THIS LINE!
document.writeln(j.toString());
}
document.writeln("abc");
}
But I kept get "invalid calling object" error for the marked line.
Why?
And here is my page source:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>This is JS fun!</title>
<script type="text/javascript" language="javascript" src="test.js">
</script>
</head>
<body>
<h1>1111</h1>
<h1>2222</h1>
<h1>3333</h1>
<h1>4444</h1>
<input type="button" onclick="test()" value="click me!" />
</body>
</html>
Below is my screenshot:

The error comes because you are running the code after the page is completed.
The first document.writeln call creates a new document with only the string in it. That means that the collection in nodes is no longer valid. It is a collection of elements in a document that doesn't exist any more, so you can't use any of the properties (like length) of the collection any more.
If you run the code while the page is being created, it works fine: http://jsfiddle.net/Guffa/4w949/
OK, I may have figured it out.
I tried this:
function test() {
var nodes = document.getElementsByTagName("h1");
document.writeln(nodes.length); // 1st writeln
nodes2 = document.getElementsByTagName("h1");
alert(nodes2.length); // <========= MARK1
for (var j = 0; j < nodes2.length; j++) {
alert(j);
}
document.writeln("abc");
}
No error for above code. but the MARK1 line gives 0. Because after the 1st writeln, the complete page content is re-constructed, there's no < h1 > tag in the newly constructed page any more.
And then I changed the above code to this:
function test() {
var nodes = document.getElementsByTagName("h1");
document.writeln(nodes.length + "<h1>new h1</h1>"); // ADD a new < h1 > tag
nodes2 = document.getElementsByTagName("h1");
alert("node2 length = " + nodes2.length); //MARKED
for (var j = 0; j < nodes2.length; j++) {
alert(j);
}
document.writeln("abc");
}
Now the MARKED line gave me expected length, 1. Because I put a new < h1 > tag into the newly constructed document.
As to the Invalid Calling Object error. I think because the document is re-constructed with writeln, all the DOM objects previously obtained with the old invalidated document object will be invalided, too.
The key is the implicit creation of a new document by document.writeln method.
Please correct me if I am wrong.
Thanks Guffa for the insight.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With