NodeList何时处于活动状态,何时处于静态状态?


69

从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。

所以....有点烦!是否有中央参考说明哪些方法返回活动列表,哪些方法返回静态列表,而无需单独检查DOM API的所有各个部分?这里有工作规则吗?


Answers:


130

有关每种方法的信息,详细说明了该方法是否有效,但是似乎没有确定该方法的标准约定。

document.getElementsByClassName()HTMLCollection并且是活的。

document.getElementsByTagName()HTMLCollection并且是活的。

document.getElementsByName()是一个NodeList并且是活的。

document.querySelectorAll()是一个NodeList并且没有生命。

HTMLCollections一直存在。

AnHTMLCollection是节点列表。单个节点可以由序号索引或节点的被访问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

因此,HTMLCollections和NodeLists都是集合。anHTMLCollection始终是Elements在DOM中的实时显示,而aNodeList是具有Nodes的更通用的构造,可能在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>


3

我不知道是否有中央参考,但是这些是我知道的return HTMLCollections和live NodeLists的方法和属性:

方法

  • parentNode.getElementsByClassName() -返回一个 HTMLCollection
  • parentNode.getElementsByTagName()   -返回一个 HTMLCollection
  • parentNode.getElementsByTagNameNS() -返回一个 HTMLCollection
  •   document.getElementsByName()      -返回一个 NodeList

物产

  • parentNode.children   -返回一个 HTMLCollection
  •       Node.childNodes -返回一个 NodeList
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.