NodeList interface, HTMLCollection interface

Nodes are all single objects, and sometimes a data structure is needed that can accommodate multiple nodes. DOM provides two types of node collections to hold multiple nodes: NodeList and HTMLCollection.

Both of these collections belong to interface specifications. Many DOM properties and methods return results as NodeList instances or HTMLCollection instances. The main difference is that NodeList can contain various types of nodes, and HTMLCollection can only contain HTML element nodes.

NodeList interface

Overview

The NodeList instance is an array-like object, and its members are node objects. The NodeList instance can be obtained by the following method.

-Node.childNodes -document.querySelectorAll() and other node search methods

document.body.childNodes instanceof NodeList; // true

The NodeList instance is much like an array, you can use the length property and the forEach method. However, it is not an array, and you cannot use methods specific to arrays such as pop or push.

var children = document.body.childNodes;

Array.isArray(children); // false

children.length; // 34
children.forEach(console.log);

In the above code, the NodeList instance children is not an array, but has the length property and the forEach method.

If the NodeList instance wants to use the array method, it can be converted to a real array.

var children = document.body.childNodes;
var nodeArr = Array.prototype.slice.call(children);

In addition to using the forEach method to traverse the NodeList instance, you can also use the for loop.

var children = document.body.childNodes;

for (var i = 0; i < children.length; i++) {
  var item = children[i];
}

Note that the NodeList instance may be a dynamic collection or a static collection. The so-called dynamic collection is a living collection. When the DOM deletes or adds a related node, it will be immediately reflected in the NodeList instance. Currently, only Node.childNodes returns a dynamic collection, and other NodeLists are static collections.

var children = document.body.childNodes;
children.length; // 18
document.body.appendChild(document.createElement("p"));
children.length; // 19

In the above code, the document adds a child node, and the length property of the NodeList instance children increases by 1.

NodeList.prototype.length

The length property returns the number of nodes contained in the NodeList instance.

document.querySelectorAll("xxx").length;
// 0

In the above code, document.querySelectorAll returns a NodeList collection. For those HTML tags that do not exist, the length attribute returns 0.

NodeList.prototype.forEach()

The forEach method is used to traverse all the members of the NodeList. It accepts a callback function as a parameter, and executes this callback function once for each round of traversal. The usage is exactly the same as the forEach method of the array instance.

var children = document.body.childNodes;
children.forEach(function f(item, i, list) {
  // ...
}, this);

In the above code, the three parameters of the callback function f are the current member, position, and current NodeList instance in sequence. The second parameter of the forEach method is used to bind the this inside the callback function. This parameter can be omitted.

NodeList.prototype.item()

The item method accepts an integer value as a parameter, indicating the position of the member, and returns the member at that position.

document.body.childNodes.item(0);

In the above code, item(0) returns the first member.

If the parameter value is greater than the actual length, or the index is illegal (such as a negative number), the item method returns null. If the parameter is omitted, the item method will report an error.

For all array-like objects, you can use the square bracket operator to remove members. Under normal circumstances, the square bracket operator is used instead of the item method.

document.body.childNodes[0];

NodeList.prototype.keys(), NodeList.prototype.values(), NodeList.prototype.entries()

These three methods all return an ES6 iterator object, which can be traversed by for...of to obtain information about each member. The difference is that keys() returns the iterator of the key name, values() returns the iterator of the key value, and the iterator returned by entries() contains both key name and key value information.

var children = document.body.childNodes;

for (var key of children.keys()) {
  console.log(key);
}
// 0
// 1
// 2
// ...

for (var value of children.values()) {
  console.log(value);
}
// #text
// <script>
// ...

for (var entry of children.entries()) {
  console.log(entry);
}
// Array [0, #text]
// Array [1, <script>]
// ...

HTMLCollection interface

Overview

HTMLCollection is a collection of node objects, which can only contain element nodes (element), and cannot contain other types of nodes. Its return value is an array-like object, but unlike the NodeList interface, HTMLCollection does not have a forEach method and can only be traversed using for loops.

What returns the HTMLCollection instance is mainly the collection properties of some Document objects, such as document.links, document.forms, document.images, etc.

document.links instanceof HTMLCollection; // true

The HTMLCollection instances are all dynamic collections, and the changes of nodes will be reflected in the collection in real time.

If the element node has the id or name attribute, then on the HTMLCollection instance, you can use the id attribute or the name attribute to refer to the node element. If there is no corresponding node, null is returned.

// HTML code is as follows
// <img id="pic" src="http://example.com/foo.jpg">

var pic = document.getElementById("pic");
document.images.pic === pic; // true

In the above code, document.images is an instance of HTMLCollection, which can be retrieved from the HTMLCollection instance through the value of the id attribute of the <img> element.

HTMLCollection.prototype.length

The length property returns the number of members contained in the HTMLCollection instance.

document.links.length; // 18

HTMLCollection.prototype.item()

The item method accepts an integer value as a parameter, indicating the position of the member, and returns the member at that position.

var c = document.images;
var img0 = c.item(0);

In the above code, item(0) means to return the member at position 0. Since the square bracket operator has the same effect and is more convenient to use, in general, the square bracket operator is always used.

If the parameter value exceeds the number of members or is illegal (for example, less than 0), the item method returns null.

HTMLCollection.prototype.namedItem()

The parameter of the namedItem method is a string that represents the value of the id attribute or the name attribute, and returns the corresponding element node. If there is no corresponding node, null is returned.

// HTML code is as follows
// <img id="pic" src="http://example.com/foo.jpg">

var pic = document.getElementById("pic");
document.images.namedItem("pic") === pic; // true