我已经编写了以下代码:
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?
fiddle :http://jsfiddle.net/RL54Z/3/
我不必在第五行和第六行之间编写
childs=foo.getElementsByTagName("*");
,从而可以更新childs.length
。怎么会这样?
最佳答案
DOM中的大多数节点列表(例如从getElementsBy*
,querySelectorAll
和Node.childNodes
返回)不是简单的Arrays而是NodeList
对象。 NodeList
对象通常是“事件的”,因为对文档的更改会自动传播到Nodelist
对象。 (异常(exception)是querySelectorAll
的结果,该结果不是实时的!)
因此,如您在示例中所看到的,如果检索所有a
元素的NodeList,然后向文档中添加另一个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复制到一个普通的数组(不会更新),然后使用该数组。
在Mozilla MDC site上了解有关NodeLists的更多信息。
关于javascript - getElementsByTagName ("*")总是更新吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11271598/