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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28163033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:30:47  来源:igfitidea点击:

When is NodeList live and when is it static?

javascripthtmlnodelist

提问by temporary_user_name

From MDN for NodeList:

来自 MDN 的NodeList

In some cases, the NodeList is a live collection, which means that changes in the DOM are reflected in the collection. For example, Node.childNodes is live:

 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"

In other cases, the NodeList is a static collection, meaning any subsequent change in the DOM does not affect the content of the collection. document.querySelectorAll returns a static 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。

So .... kind of annoying! Is there any central reference for which methods return live lists and which ones return static lists, without having to check individually for all the various parts of the DOM API? Is there any ruleat work here?

所以......有点烦人!是否有任何关于哪些方法返回实时列表以及哪些方法返回静态列表的中央参考,而不必单独检查 DOM API 的所有各个部分?这里有什么工作规则吗?

回答by chiliNUT

Information about each method details if it is live or not, but there doesn't seem to be a standard convention for determining it.

有关每个方法的详细信息是否有效,但似乎没有确定它的标准约定。

document.getElementsByClassName()is an HTMLCollectionand is live.

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

document.getElementsByTagName()is an HTMLCollectionand is live.

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

document.getElementsByName()is a NodeListand is live.

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

document.querySelectorAll()is a NodeListand is notlive.

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

HTMLCollections are always live.

HTMLCollections 永远活着。

An HTMLCollectionis a list of nodes. An individual node may be accessed by either ordinal index or the node's nameor idattributes.

Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.

AnHTMLCollection是节点列表。可以通过序数索引或节点的属性nameid属性来访问单个节点。

注意:HTML DOM 中的集合被假定为活动的,这意味着它们会在底层文档更改时自动更新。

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

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

A NodeList object is a collection of nodes... The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.

NodeList 对象是节点的集合... NodeList 接口提供了节点有序集合的抽象,而不定义或限制如何实现该集合。DOM 中的 NodeList 对象是活动的。

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

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

So, both HTMLCollections and NodeLists are collections. An HTMLCollectionis always a live representation of its Elements' presence in the DOM, whereas a NodeListis a more generic construct with Nodes that may or may not be in the DOM.

所以,HTMLCollections 和NodeLists 都是集合。AnHTMLCollection始终是其Elements 在 DOM 中存在的实时表示,而 aNodeList是一种更通用的构造,其中Nodes 可能在也可能不在 DOM 中。

A collection is an object that represents a list of DOM nodes. A collection can be either live or static. Unless otherwise stated, a collection must be live.

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

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

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

So, to summarize:

所以,总结一下:

  • Collections can be either in the HTML DOM(live), or not (static)
  • .querySelectorAll()returns a NodeList that is static, meaning that
  • .querySelectorAll()returns a collection that is not in the DOM
  • 集合可以在 HTML DOM(实时)中,也可以不在(静态)中
  • .querySelectorAll()返回一个静态的 NodeList,这意味着
  • .querySelectorAll()返回一个不在 DOM 中的集合

Note that "not being in the DOM" doesn't mean the elements within static collections are removed, detached, hidden, or inaccessible. All it means is that the collection is fixed to whatever the selector matches at the time you initiate it.

请注意,“不在 DOM 中”并不意味着静态集合中的元素被移除、分离、隐藏或不可访问。这意味着该集合在您启动它时固定为选择器匹配的任何内容。

Well, here is a method to determine if a collection is live. It appends a clone of a member of the collection (so it will match the selector) to its parent, checks to see if the length changed, and then removes it so the page is not affected.

好吧,这是一种确定集合是否处于活动状态的方法。它将集合成员的克隆(因此它将与选择器匹配)附加到其父项,检查长度是否发生变化,然后将其删除以使页面不受影响。

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>

回答by Barmar

I don't know if there's a central reference, but these are the methods and properties I know of that return HTMLCollections and live NodeLists:

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

Methods

方法

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

Properties

特性

  • parentNode.children??- returns an HTMLCollection
  • ??????Node.childNodes- returns a NodeList
  • parentNode.children??- 返回一个 HTMLCollection
  • ??????Node.childNodes- 返回一个 NodeList