Javascript getElementsByTagName(“*”)是否始终更新?

Javascript getElementsByTagName(“*”)是否始终更新?,javascript,dom,getelementsbytagname,Javascript,Dom,Getelementsbytagname,我制定了以下代码: 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? 小提琴: 我不必编写childs=foo.getElem

我制定了以下代码:

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?
小提琴:

我不必编写
childs=foo.getElementsByTagName(“*”)位于第五行和第六行之间,以便更新
childs.length

怎么可能呢?

如果你读了这本书,你不会感到惊讶

返回具有给定标记名的元素列表。将搜索指定元素下的子树,不包括元素本身。返回的列表是活动的,这意味着它会自动用DOM树更新自身。因此,不需要使用相同的元素和参数多次调用element.getElementsByTagName


DOM中的大多数节点列表(例如,从
getElementsBy*
querySelectorAll
Node.childNodes
返回)不是简单的数组,而是
NodeList
对象<代码>节点列表
对象通常是“活动”的,因为对文档的更改会自动传播到
节点列表
对象。(异常是来自
querySelectorAll
的结果,它不是活动的!)

因此,正如您在示例中所看到的,如果检索所有
a
元素的节点列表,然后将另一个
a
元素添加到文档中,那么
a
将显示在节点列表对象中

这就是为什么在对文档进行更改的同时迭代节点列表是不安全的。例如,该代码将以令人惊讶的方式运行:

var NodeListA = document.getElementsByTagName('a');

for (var i=0; i<NodeListA.length; ++i) {
   // UNSAFE: don't do this!
   NodeListA[i].parentNode.removeChild(NodeListA[i]);
}
var NodeListA=document.getElementsByTagName('a');
对于(var i=0;i