[英]When is NodeList live and when is it static?
来自 MDN 的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。
所以......有点烦人! 对于哪些方法返回实时列表以及哪些方法返回静态列表,是否有任何中央参考,而不必单独检查 DOM API 的所有各个部分? 这里有什么工作规则吗?
有关每个方法的详细信息是否有效,但似乎没有确定它的标准约定。
document.getElementsByClassName()
是一个HTMLCollection
并且是实时的。
document.getElementsByTagName()
是一个HTMLCollection
并且是实时的。
document.getElementsByName()
是一个NodeList
并且是实时的。
document.querySelectorAll()
是一个NodeList
并且不是实时的。
HTMLCollection
始终处于活动状态。
HTMLCollection
是一个节点列表。 可以通过序数索引或节点的name
或id
属性访问单个节点。注意:HTML DOM 中的集合被假定为活动的,这意味着它们会在底层文档更改时自动更新。
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506
NodeList 对象是节点的集合... NodeList 接口提供了节点有序集合的抽象,而不定义或限制该集合的实现方式。 DOM 中的 NodeList 对象是活动的。
http://www.w3.org/TR/DOM-Level-3-Core/core.html#td-live
因此, HTMLCollection
和NodeList
都是集合。 HTMLCollection
始终是其Element
存在于 DOM 中的实时表示,而NodeList
是一种更通用的构造,其中Node
可能存在也可能不存在于 DOM 中。
集合是表示 DOM 节点列表的对象。 集合可以是实时的或静态的。 除非另有说明,否则集合必须是实时的。
http://www.w3.org/TR/2012/WD-dom-20120405/#collections
所以,总结一下:
.querySelectorAll()
返回一个静态的 NodeList,这意味着.querySelectorAll()
返回一个不在 DOM 中的集合请注意,“不在 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>
我不知道是否有中心参考,但这些是我知道的返回HTMLCollection
和实时NodeList
的方法和属性:
parentNode.getElementsByClassName()
- 返回一个HTMLCollection
parentNode.getElementsByTagName()
- 返回一个HTMLCollection
parentNode.getElementsByTagNameNS()
- 返回一个HTMLCollection
document.getElementsByName()
- 返回一个NodeList
parentNode.children
- 返回一个HTMLCollection
Node.childNodes
- 返回一个NodeList
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.