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