我编写以下JS并在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");
}
但是我一直为标记的行弄错了“无效的调用对象”错误。
为什么?
这是我的页面来源:
<!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>
以下是我的截图:
答案 0 :(得分:12)
出现错误的原因是您在页面完成后运行代码。
第一个document.writeln
调用会创建一个只包含字符串的新文档。这意味着nodes
中的集合不再有效。它是文档中不再存在的元素集合,因此您不能再使用集合的任何属性(如length
)。
如果您在创建页面时运行代码,它可以正常工作:http://jsfiddle.net/Guffa/4w949/
答案 1 :(得分:3)
好的,我可能已经弄清楚了。
我试过了:
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");
}
上述代码没有错误。但 MARK1 行给出0.因为在 1st writeln 之后,重新构建了完整的页面内容,没有&lt; h1&gt;在新构建的页面中标记。
然后我将上面的代码更改为:
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");
}
现在 MARKED 行给了我预期的长度,1。因为我放了一个新的&lt; h1&gt;标记到新构建的文档中。
关于无效的调用对象错误。我认为因为文档是使用writeln重新构造的,所以先前使用旧的无效文档对象获得的所有DOM对象也将被无效。
关键是document.writeln方法隐式创建新文档。
如果我错了,请纠正我。
感谢Guffa的洞察力。
答案 2 :(得分:-7)
j
是一个变量计数器,而不是对象。
您需要nodes.item(j).toString();