When is NodeList live and when is it static?

天大地大妈咪最大 提交于 2019-11-26 10:15:34
chiliNUT

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

document.getElementsByClassName() is an HTMLCollection, and is live.

document.getElementsByTagName() is an HTMLCollection, and is live.

document.getElementsByName() is a NodeList and is live.

document.querySelectorAll() is a NodeList and is not live.

HTMLCollections appear to always be live

An HTMLCollection is a list of nodes. An individual node may be accessed by either ordinal index or the node's name or id attributes.

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

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

So, HTML Collections are always "in the dom," whereas a nodeList is a more generic construct that may or may not be in the DOM.

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.

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

Sounds good, right?

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

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

So static collections will be indicated as such in the spec. So, by this logic, document.querySelectorAll() is a collection, but it is not in the DOM. Because while collections may or may not be live, collections in the DOM must be live... This distinction is not super helpful.

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

DEMO

function isLive(collection) {
  if (collection.length < 1) {
    return undefined; //inconclusivw 
  }
  let body = document.getElementsByTagName('body')[0];
  let l1 = collection.length;
  let clone = collection.item(0).cloneNode();
  clone.style.display = "none";
  body.appendChild(clone);
  let l2 = collection.length;
  body.removeChild(clone);
  return l2 !== l1;
}



divs1 = document.getElementsByClassName('c');
console.log("document.getElementsByClassName('c'):",divs1.toString()); //"[object HTMLCollection]"


divs2 = document.querySelectorAll('.c');
console.log("document.querySelectorAll('.c'):     ",divs2.toString()); //"[object NodeList]"

divs3 = document.getElementsByName('mydiv');
console.log("document.getElementsByName('mydiv'): ",divs3.toString()); //"[object NodeList"]

console.log("isLive(divs1)",isLive(divs1)); //true
console.log("isLive(divs2)",isLive(divs2)); //false
console.log("isLive(divs3)",isLive(divs3)); //true
<html>

<body>
  <div class="c" name="mydiv">C1</div>
  <div class="c" name="mydiv">C2</div>
</body>

</html>

I don't know if there's a central reference, but this blog post says:

document.getElementsByTagName(), document.getElementsByTagNameNS and document.getElementsByClassName() are the only options available that return “live” node lists. Looking at those methods, you may be discouraged, but don’t be.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!