从MDN for NodeList:
在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中。例如,Node.childNodes处于活动状态: var parent = document.getElementById('parent'); var child_nodes = parent.childNodes; console.log(child_nodes.length); // let's assume "2" parent.appendChild(document.createElement('div')); console.log(child_nodes.length); // should output "3" 在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容。document.querySelectorAll返回一个静态NodeList。
在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中。例如,Node.childNodes处于活动状态:
var parent = document.getElementById('parent'); var child_nodes = parent.childNodes; console.log(child_nodes.length); // let's assume "2" parent.appendChild(document.createElement('div')); console.log(child_nodes.length); // should output "3"
在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容。document.querySelectorAll返回一个静态NodeList。
所以....有点烦!是否有任何关于哪些方法返回活动列表和哪些方法返回静态列表的中心参考,而不必单独检查DOMAPI的所有各个部分?这里有工作规则吗?
有关每种方法的信息,详细说明了该方法是否有效,但是似乎没有确定该方法的标准约定。
document.getElementsByClassName()是HTMLCollection并且是活的。
document.getElementsByClassName()
HTMLCollection
document.getElementsByTagName()是HTMLCollection并且是活的。
document.getElementsByTagName()
document.getElementsByName()是一个NodeList并且是活的。
document.getElementsByName()
NodeList
document.querySelectorAll()是一个NodeList并且 没有 生命。
document.querySelectorAll()
HTMLCollections一直存在。
An HTMLCollection是节点列表。单个节点可以由序号索引或节点的被访问name或id属性。 注意:HTML DOM中的集合被认为是实时的,这意味着当基础文档发生更改时,它们会自动更新。 NodeList对象是节点的集合… NodeList接口提供了节点的有序集合的抽象,而没有定义或约束该集合的实现方式。DOM中的NodeList对象是活动的。
An HTMLCollection是节点列表。单个节点可以由序号索引或节点的被访问name或id属性。
name
id
注意:HTML DOM中的集合被认为是实时的,这意味着当基础文档发生更改时,它们会自动更新。
NodeList对象是节点的集合… NodeList接口提供了节点的有序集合的抽象,而没有定义或约束该集合的实现方式。DOM中的NodeList对象是活动的。
因此,HTMLCollections和NodeLists都是集合。anHTMLCollection始终是Elements在DOM中的实时显示,而a NodeList是具有Nodes的更通用的构造,可能在DOM中也可能不在。
Element
Node
集合是代表DOM节点列表的对象。集合可以是实时的也可以是静态的。除非另有说明,否则收集必须是实时的。
因此,总结一下:
.querySelectorAll()
请注意,“不在DOM中”并不意味着静态集合中的元素将被删除,分离,隐藏或不可访问。这意味着将集合固定到启动它时选择器匹配的任何内容。
好吧,这是一种确定集合是否处于活动状态的方法。它将集合成员的克隆(因此它将与选择器匹配)附加到其父集合,检查长度是否更改,然后将其删除,以使页面不受影响。
function isLive(collection) { if (HTMLCollection.prototype.isPrototypeOf(collection)) return true // HTMLCollections are always live const length = collection.length; if (!length) return undefined; // Inconclusive const el = collection.item(0); const parent = el.parentNode; const clone = el.cloneNode(); clone.style.setProperty('display', 'none', 'important'); parent.appendChild(clone); const live = collection.length !== length; parent.removeChild(clone); return live; } const divs1 = document.getElementsByClassName('c'); const divs2 = document.getElementsByTagName('span'); const divs3 = document.getElementsByName('notFound'); const divs4 = document.querySelectorAll('.c'); console.log("document.getElementsByClassName('c'):", divs1.toString()); // [object HTMLCollection] console.log("document.getElementsByTagName('notFound'):", divs2.toString()); // [object HTMLCollection] console.log("document.getElementsByName('notFound'):", divs3.toString()); // [object NodeList] console.log("document.querySelectorAll('.c'):", divs4.toString()); // [object NodeList] console.log('isLive(divs1)', isLive(divs1)); // true console.log('isLive(divs2)', isLive(divs2)); // true console.log('isLive(divs3)', isLive(divs3)); // undefined console.log('isLive(divs4)', isLive(divs4)); // false <div> <div class="c">C1</div> <div class="c">C2</div> </div> <div> <div class="c">C3</div> <div class="c">C4</div> </div>