NodeList何时生效,何时是静态的?

tem*_*ame 58 html javascript nodelist

从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"
Run Code Online (Sandbox Code Playgroud)

在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容.document.querySelectorAll返回一个静态NodeList.

所以....有点烦人!对于哪些方法返回实时列表以及哪些方法返回静态列表,是否有任何中心引用,而无需单独检查DOM API的所有各个部分?这里有什么规则吗?

chi*_*NUT 105

有关每种方法的详细信息,如果它是否有效,但似乎没有确定它的标准惯例.

document.getElementsByClassName()是一个HTMLCollection,而且是活的.

document.getElementsByTagName()是一个HTMLCollection,而且是活的.

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

document.querySelectorAll()是一个NodeList而且不是活的.

HTMLCollection似乎总是活着的

HTMLCollection是节点列表.可以通过序数索引或节点的名称或id属性来访问单个节点.

注意:HTML DOM中的集合被假定为实时,这意味着它们会在更改基础文档时自动更新.

http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506

因此,HTML集合总是 "在dom中",而a HTMLCollection是一个更通用的构造,可能在DOM中,也可能不在DOM中.

NodeList对象是节点的集合...... NodeList接口提供有序节点集合的抽象,而不定义或约束此集合的实现方式.DOM中的NodeList对象是实时的.

http://www.w3.org/TR/DOM-Level-3-Core/core.html#td-live

听起来不错吧?

集合是表示DOM节点列表的对象.集合可以是实时的也可以是静态的.除非另有说明,否则收藏必须是现场直播.

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

因此静态集合将在规范中表示.所以,通过这个逻辑,name是一个集合,但它不在 DOM中.因为虽然集合可能是也可能不是,但DOM中的集合必须是实时的...这种区别并不是非常有用.

好吧,这是确定a id是否存在的快速方法; 它将集合成员的克隆附加到HTMLCollection(因此它将匹配选择器),并检查长度是否已更改,然后将其删除(因此页面不受影响)

DEMO

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
Run Code Online (Sandbox Code Playgroud)
<div>
    <div class="c">C1</div>
    <div class="c">C2</div>
</div>
<div>
    <div class="c">C3</div>
    <div class="c">C4</div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 重温这一点,这是一个很好的答案.你应该获得赏金. (2认同)