繁体   English   中英

NodeList 什么时候上线,什么时候是静态的?

[英]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是一个节点列表。 可以通过序数索引或节点的nameid属性访问单个节点。

注意: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

因此, HTMLCollectionNodeList都是集合。 HTMLCollection始终是其Element存在于 DOM 中的实时表示,而NodeList是一种更通用的构造,其中Node可能存在也可能不存在于 DOM 中。

集合是表示 DOM 节点列表的对象。 集合可以是实时的或静态的。 除非另有说明,否则集合必须是实时的。

http://www.w3.org/TR/2012/WD-dom-20120405/#collections

所以,总结一下:

  • 集合可以在 HTML DOM (实时)中,也可以不在(静态)中
  • .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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM