Node interface

All DOM node objects inherit the Node interface and have some common properties and methods. This is the basis of DOM manipulation.

Attributes

Node.prototype.nodeType

The nodeType property returns an integer value indicating the type of node.

document.nodeType; // 9

In the above code, the type value of the document node is 9.

The Node object defines several constants corresponding to these types of values.

document.nodeType === Node.DOCUMENT_NODE; // true

In the above code, the nodeType property of the document node is equal to the constant Node.DOCUMENT_NODE.

The value of the nodeType property of different nodes and the corresponding constants are as follows.

-Document node (document): 9, corresponding to the constant Node.DOCUMENT_NODE -Element node (element): 1, corresponding to the constant Node.ELEMENT_NODE -Attr: 2, corresponding to the constant Node.ATTRIBUTE_NODE -Text node (text): 3, corresponding to the constant Node.TEXT_NODE -Document Fragment: 11, corresponding to the constant Node.DOCUMENT_FRAGMENT_NODE -DocumentType: 10, corresponding to the constant Node.DOCUMENT_TYPE_NODE -Comment: 8, corresponding to the constant Node.COMMENT_NODE

When determining the node type, using the nodeType property is a common method.

var node = document.documentElement.firstChild;
if (node.nodeType === Node.ELEMENT_NODE) ​​{
  console.log('This node is an element node');
}

Node.prototype.nodeName

The nodeName property returns the name of the node.

// HTML code is as follows
// <div id="d1">hello world</div>
var div = document.getElementById("d1");
div.nodeName; // "DIV"

In the above code, the nodeName attribute of the element node <div> is the uppercase tag name DIV.

The values ​​of the nodeName attribute of different nodes are as follows.

-Document node (document): #document -Element node (element): tag name in uppercase -Attribute node (attr): the name of the attribute -Text node (text): #text -Document Fragment node (DocumentFragment): #document-fragment -Document Type node (DocumentType): the type of document -Comment node (Comment): #comment

Node.prototype.nodeValue

The nodeValue property returns a string representing the text value of the current node itself. This property can be read and written.

Only text nodes (text), comment nodes (comment) and attribute nodes (attr) have text values, so the nodeValue of these three types of nodes can return results, and all other types of nodes will return null. Similarly, only these three types of nodes can set the value of the nodeValue property, and other types of nodes are invalid.

// HTML code is as follows
// <div id="d1">hello world</div>
var div = document.getElementById("d1");
div.nodeValue; // null
div.firstChild.nodeValue; // "hello world"

In the above code, div is the element node, and the nodeValue property returns null. div.firstChild is a text node, so it can return a text value.

Node.prototype.textContent

The textContent property returns the text content of the current node and all its descendants.

// HTML code is
// <div id="divA">This is <span>some</span> text</div>

document.getElementById("divA").textContent;
// This is some text

The textContent attribute automatically ignores the HTML tags inside the current node and returns all text content.

This attribute is readable and writable. Setting the value of this attribute will replace all the original child nodes with a new text node. It also has the advantage of automatically escaping HTML tags. This is very suitable for user-provided content.

document.getElementById("foo").textContent = "<p>GoodBye!</p>";

When the above code inserts text, it will interpret the <p> tag as text instead of processing it as a tag.

For text nodes (text), comment nodes (comment) and attribute nodes (attr), the value of the textContent attribute is the same as the nodeValue attribute. For other types of nodes, this attribute will concatenate the contents of each child node (not including the comment node) together and return. If a node has no children, an empty string is returned.

The textContent property of the document node (document) and the document type node (doctype) is null. If you want to read the content of the entire document, you can use document.documentElement.textContent.

Node.prototype.baseURI

The baseURI property returns a string representing the absolute path of the current web page. The browser calculates the relative path URL on the web page based on this attribute. This attribute is read-only.

// The URL of the current webpage is
// http://www.example.com/index.html
document.baseURI;
// "http://www.example.com/index.html"

If the URL of the web page cannot be read, the baseURI property returns null.

The value of this attribute is generally determined by the URL of the current website (ie the window.location attribute), but you can use the HTML <base> tag to change the value of this attribute.

<base href="http://www.example.com/page.html" />

After it is set, the baseURI attribute returns the value set by the <base> tag.

Node.prototype.ownerDocument

The Node.ownerDocument property returns the top-level document object where the current node is located, that is, the document object.

var d = p.ownerDocument;
d === document; // true

The ownerDocument property of the document object itself returns null.

Node.prototype.nextSibling

The Node.nextSibling property returns the first sibling node immediately following the current node. If there is no sibling node behind the current node, null is returned.

// HTML code is as follows
// <div id="d1">hello</div><div id="d2">world</div>
var d1 = document.getElementById("d1");
var d2 = document.getElementById("d2");

d1.nextSibling === d2; // true

In the above code, d1.nextSibling is the sibling node d2 immediately following d1.

Note that this attribute also includes text nodes and comment nodes (<!-- comment -->). Therefore, if there is a space after the current node, this attribute will return a text node with a space as the content.

The nextSibling attribute can be used to traverse all child nodes.

var el = document.getElementById("div1").firstChild;

while (el !== null) {
  console.log(el.nodeName);
  el = el.nextSibling;
}

The above code traverses all child nodes of the div1 node.

Node.prototype.previousSibling

The previousSibling property returns the nearest sibling node in front of the current node. If there is no node at the same level before the current node, null is returned.

// HTML code is as follows
// <div id="d1">hello</div><div id="d2">world</div>
var d1 = document.getElementById("d1");
var d2 = document.getElementById("d2");

d2.previousSibling === d1; // true

In the above code, d2.previousSibling is the sibling node d1 before d2.

Note that this attribute also includes text nodes and comment nodes. Therefore, if there is a space in front of the current node, this attribute will return a text node with a space in the content.

Node.prototype.parentNode

The parentNode property returns the parent node of the current node. For a node, its parent node can only be of three types: element node (element), document node (document) and document fragment node (documentfragment).

if (node.parentNode) {
  node.parentNode.removeChild(node);
}

In the above code, the node node is removed from the document through the node.parentNode property.

The parent node of document node (document) and document fragment node (documentfragment) are both null. In addition, for those nodes that have not been inserted into the DOM tree after generation, the parent node is also null.

Node.prototype.parentElement

The parentElement property returns the parent element node of the current node. If the current node has no parent node, or the parent node type is not an element node, then null is returned.

if (node.parentElement) {
  node.parentElement.style.color = "red";
}

In the above code, the style of the parent element node is set to red.

Since the parent node can only be of three types: element node, document node (document) and document fragment node (documentfragment). The parentElement property is equivalent to excluding the latter two parent nodes.

Node.prototype.firstChild, Node.prototype.lastChild

The firstChild property returns the first child node of the current node. If the current node has no children, it returns null.

// HTML code is as follows
// <p id="p1"><span>First span</span></p>
var p1 = document.getElementById("p1");
p1.firstChild.nodeName; // "SPAN"

In the above code, the first child node of the p element is the span element.

Note that in addition to element nodes returned by firstChild may also be text nodes or comment nodes.

// HTML code is as follows
// <p id="p1">
// <span>First span</span>
// </p>
var p1 = document.getElementById("p1");
p1.firstChild.nodeName; // "#text"

In the above code, there is a blank character between the p element and the span element, which causes the text node returned by firstChild.

The lastChild property returns the last child node of the current node. If the current node has no children, it returns null. The usage is the same as the firstChild property.

Node.prototype.childNodes

The childNodes property returns an array-like object (NodeList collection), the members include all child nodes of the current node.

var children = document.querySelector("ul").childNodes;

In the above code, children is all the child nodes of the ul element.

Using this attribute, you can traverse all the child nodes of a node.

var div = document.getElementById("div1");
var children = div.childNodes;

for (var i = 0; i < children.length; i++) {
  // ...
}

The document node (document) has two child nodes: the document type node (docType) and the HTML root element node.

var children = document.childNodes;
for (var i = 0; i < children.length; i++) {
  console.log(children[i].nodeType);
}
// 10
// 1

In the above code, the type of the first child node of the document node is 10 (ie, the document type node), and the type of the second child node is 1 (ie, the element node).

Note that in addition to element nodes, the return value of the childNodes property also includes text nodes and comment nodes. If the current node does not include any child nodes, an empty NodeList collection is returned. Since the NodeList object is a dynamic collection, once the child node changes, it will immediately be reflected in the returned result.

Node.prototype.isConnected

The isConnected property returns a boolean value indicating whether the current node is in the document.

var test = document.createElement("p");
test.isConnected; // false

document.body.appendChild(test);
test.isConnected; // true

In the above code, the test node is a node generated by the script. Before inserting the document, the isConnected property returns false, and after inserting it returns true.

Method

Node.prototype.appendChild()

The appendChild() method accepts a node object as a parameter and uses it as the last child node to insert into the current node. The return value of this method is the child node of the inserted document.

var p = document.createElement("p");
document.body.appendChild(p);

The above code creates a new <p> node and inserts it at the end of document.body.

If the parameter node is an existing node in the DOM, the appendChild() method will move it from the original position to the new position.

var div = document.getElementById("myDiv");
document.body.appendChild(div);

In the above code, an existing node myDiv is inserted. As a result, the node will move from its original position to the end of document.body.

If the parameter of the appendChild() method is the DocumentFragment node, then all child nodes of DocumentFragment are inserted instead of the DocumentFragment node itself. The return value is an empty DocumentFragment node.

Node.prototype.hasChildNodes()

The hasChildNodes method returns a boolean value indicating whether the current node has child nodes.

var foo = document.getElementById("foo");

if (foo.hasChildNodes()) {
  foo.removeChild(foo.childNodes[0]);
}

The above code means that if the foo node has child nodes, remove the first child node.

Note that child nodes include all types of nodes, not just element nodes. Even if the node only contains a space, the hasChildNodes method will return true.

There are many ways to determine whether a node has child nodes, the following are three of them.

-node.hasChildNodes() -node.firstChild !== null -node.childNodes && node.childNodes.length> 0

The hasChildNodes method combines the firstChild property and the nextSibling property to traverse all descendant nodes of the current node.

function DOMComb(parent, callback) {
  if (parent.hasChildNodes()) {
    for (var node = parent.firstChild; node; node = node.nextSibling) {
      DOMComb(node, callback);
    }
  }
  callback(parent);
}

// usage
DOMComb(document.body, console.log);

In the above code, the first parameter of the DOMComb function is a specified node, and the second parameter is the callback function. This callback function will act on the specified node in turn, and all descendant nodes of the specified node.

Node.prototype.cloneNode()

The cloneNode method is used to clone a node. It accepts a Boolean value as a parameter, which indicates whether to clone child nodes at the same time. Its return value is a cloned new node.

var cloneUL = document.querySelector("ul").cloneNode(true);

This method has some points of attention.

(1) Cloning a node will copy all the attributes of the node, but will lose the addEventListener method and the on- attribute (ie node.onclick = fn), and add the event callback function on this node.

(2) The node returned by this method is not in the document, that is, there is no parent node, and it must be added to the document using a method such as Node.appendChild.

(3) After cloning a node, two webpage elements with the same id attribute (ie id="xxx") may appear in the DOM. At this time, the id attribute of one of the elements should be modified. If the original node has a name attribute, it may also need to be modified.

Node.prototype.insertBefore()

The insertBefore method is used to insert a node into a specified position inside the parent node.

var insertedNode = parentNode.insertBefore(newNode, referenceNode);

The insertBefore method accepts two parameters, the first parameter is the node newNode to be inserted, and the second parameter is a child node referenceNode inside the parent node parentNode. newNode will be inserted in front of the child node referenceNode. The return value is the inserted new node newNode.

var p = document.createElement("p");
document.body.insertBefore(p, document.body.firstChild);

In the above code, create a new <p> node and insert it in front of document.body.firstChild, which becomes the first child node of document.body.

If the second parameter of the insertBefore method is null, the new node will be inserted at the last position inside the current node, that is, it will become the last child node.

var p = document.createElement("p");
document.body.insertBefore(p, null);

In the above code, p will become the last child node of document.body. This also shows that the second parameter of insertBefore cannot be omitted.

Note that if the node to be inserted is an existing node in the current DOM, the node will be removed from its original position and inserted into a new position.

Since there is no insertAfter method, if the new node is to be inserted behind a child node of the parent node, you can use the insertBefore method combined with the nextSibling property to simulate.

parent.insertBefore(s1, s2.nextSibling);

In the above code, parent is the parent node, s1 is a brand new node, and s2 can insert the s1 node after the s2 node. If s2 is the last child node of the current node, then s2.nextSibling returns null, then the s1 node will be inserted at the end of the current node, becoming the last child node of the current node, which is equal to tight Follow behind s2.

If the node to be inserted is of type DocumentFragment, then all child nodes of DocumentFragment will be inserted instead of the DocumentFragment node itself. The return value will be an empty DocumentFragment node.

Node.prototype.removeChild()

The removeChild method accepts a child node as a parameter, which is used to remove the child node from the current node. The return value is the removed child node.

var divA = document.getElementById("A");
divA.parentNode.removeChild(divA);

The above code removes the divA node. Note that this method is called on the parent node of divA, not on divA.

Here is how to remove all child nodes of the current node.

var element = document.getElementById("top");
while (element.firstChild) {
  element.removeChild(element.firstChild);
}

The removed node still exists in memory, but is no longer part of the DOM. Therefore, after a node is removed, it can still be used, such as inserted under another node.

If the parameter node is not a child node of the current node, the removeChild method will report an error.

Node.prototype.replaceChild()

The replaceChild method is used to replace a child node of the current node with a new node.

var replacedNode = parentNode.replaceChild(newChild, oldChild);

In the above code, the replaceChild method accepts two parameters. The first parameter newChild is the new node to be replaced, and the second parameter oldChild is the child node to be replaced. The return value is the node oldChild that was replaced.

var divA = document.getElementById("divA");
var newSpan = document.createElement("span");
newSpan.textContent = "Hello World!";
divA.parentNode.replaceChild(newSpan, divA);

The above code is how to replace the specified node divA.

Node.prototype.contains()

The contains method returns a boolean value indicating whether the parameter node meets one of the following three conditions.

-The parameter node is the current node. -The parameter node is a child node of the current node. -The parameter node is the descendant node of the current node.

document.body.contains(node);

The above code checks whether the parameter node node is included in the current document.

Note that the current node passes into the contains method, and returns true.

nodeA.contains(nodeA); // true

Node.prototype.compareDocumentPosition()

The usage of the compareDocumentPosition method is exactly the same as the contains method. It returns a six-bit binary value that represents the relationship between the parameter node and the current node.

Binary valueDecimal valueMeaning
0000000Two nodes are the same
0000011The two nodes are not in the same document (that is, one node is not in the current document)
0000102The parameter node is in front of the current node
0001004The parameter node is behind the current node
0010008The parameter node contains the current node
01000016The current node contains parameter nodes
10000032Internal use of the browser
// HTML code is as follows
// <div id="mydiv">
// <form><input id="test" /></form>
// </div>

var div = document.getElementById("mydiv");
var input = document.getElementById("test");

div.compareDocumentPosition(input); // 20
input.compareDocumentPosition(div); // 10

In the above code, the node div contains the node input (binary 010000), and the node input is behind the node div (binary 000100), so the first compareDocumentPosition method returns 20 (Binary 010100, ie 010000 + 000100), the second compareDocumentPosition method returns 10 (Binary 001010).

Since the meaning of the return value of compareDocumentPosition is defined in each bit position, if you want to check a specific meaning, you need to use the bit position operator.

var head = document.head;
var body = document.body;
if (head.compareDocumentPosition(body) & 4) {
  console.log("The document structure is correct");
} else {
  console.log("<body> cannot be in front of <head>");
}

In the above code, the return value of compareDocumentPosition is ANDed (&) with 4 (also known as mask), and a Boolean value is obtained, indicating whether <head> is before <body>.

Node.prototype.isEqualNode(), Node.prototype.isSameNode()

The isEqualNode method returns a boolean value, which is used to check whether two nodes are equal. The so-called equal nodes refer to two nodes that have the same type, the same attributes, and the same child nodes.

var p1 = document.createElement("p");
var p2 = document.createElement("p");

p1.isEqualNode(p2); // true

The isSameNode method returns a boolean value indicating whether the two nodes are the same node.

var p1 = document.createElement("p");
var p2 = document.createElement("p");

p1.isSameNode(p2); // false
p1.isSameNode(p1); // true

Node.prototype.normalize()

The normalize method is used to clean up all text nodes (text) inside the current node. It removes empty text nodes and merges adjacent text nodes into one, which means that there are no empty text nodes and adjacent text nodes.

var wrapper = document.createElement("div");

wrapper.appendChild(document.createTextNode("Part 1"));
wrapper.appendChild(document.createTextNode("Part 2"));

wrapper.childNodes.length; // 2
wrapper.normalize();
wrapper.childNodes.length; // 1

Before the above code uses the normalize method, the wrapper node has two adjacent text child nodes. After using the normalize method, the two text child nodes are merged into one.

This method is the inverse method of Text.splitText, you can refer to the chapter "Text Node Object" for more details.

Node.prototype.getRootNode()

The getRootNode() method returns the root node document of the document where the current node is located, which has the same effect as the ownerDocument property.

document.body.firstChild.getRootNode() === document;
// true
document.body.firstChild.getRootNode() ===
  document.body.firstChild.ownerDocument;
// true

This method can be used on the document node itself, which is different from document.ownerDocument.

document.getRootNode(); // document
document.ownerDocument; // null