我已经编写了这段代码:
var foo=document.createElement("div");
var childs=foo.getElementsByTagName("*");
console.log(childs.length);//0 OK
var a=document.createElement("a");
foo.appendChild(a);
console.log(childs.length);//1 WTF?
一把小提琴:http://jsfiddle.net/RL54Z/3/ http://jsfiddle.net/RL54Z/3/
我不必写childs=foo.getElementsByTagName("*");
在第五行和第六行之间,这样childs.length
已更新。
怎么会这样?
DOM 中的大多数节点列表(例如从getElementsBy*
, querySelectorAll
, and Node.childNodes
) 不是简单的数组,而是NodeList
对象。NodeList
对象通常是“活动的”,因为对文档的更改会自动传播到Nodelist
目的。 (一个例外是结果querySelectorAll
,即not live!)
正如您在示例中看到的,如果您检索所有节点列表a
元素,然后添加另一个a
文档的元素,即a
将出现在您的 NodeList 对象中。
这就是为什么在对文档进行更改的同时迭代 NodeList 是不安全的。例如,这段代码将以令人惊讶的方式运行:
var NodeListA = document.getElementsByTagName('a');
for (var i=0; i<NodeListA.length; ++i) {
// UNSAFE: don't do this!
NodeListA[i].parentNode.removeChild(NodeListA[i]);
}
将会发生的情况是您最终会跳过元素!要么从 NodeList 的末尾向后迭代,要么将 NodeList 复制到普通数组(不会更新),然后使用它。
阅读有关 NodeList 的更多信息,请访问Mozilla MDC 站点 https://developer.mozilla.org/En/DOM/NodeList.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)