Although we do not need to operate DOM by ourselves in the development now, JQ before, and now there are VUE and REACT frameworks for us to use, but we also need to understand the DOM operation problems in native JS.

  • Let’s introduce it this timeDOMNode type and method of obtaining node

We believe that all content presented in the page is a node in the DOM document, such as: element tag is element node, annotation content is annotation node, text content is text node, document is document node…

I. Node type

1. Document node

  • document
  • Key memory attributes:
    • NodeType (nodeType) : 9
    • NodeName (nodeName) : “#document”
    • NodeValue (node text content) : null

2. Element nodes

  • All element tags
  • Key memory attributes:
    • NodeType (nodeType) : 1
    • NodeName (nodeName) : “upper case label name”
    • NodeValue (node text content) : null

3. Text nodes

  • Text, Spaces between tags, and newlines are also treated as text nodes
  • Key memory attributes:
    • NodeType (nodeType) : 3
    • NodeName (nodeName) : “#text”
    • NodeValue (node text content) : text content

4. Comment nodes

  • The comment
  • Key memory attributes:
    • NodeType (nodeType) : 8
    • NodeName: “#comment”
    • NodeValue (node text content) : Comment content

2. Method of obtaining nodes

Describes nodes and relationship properties between nodes based on which a specified node can be obtained

1. Get all child nodes — a collection of nodes

  • Grammar:[CONTAINER].childNodes
  • Gets all child nodes in the current container
  • Contains nodes of various types
  • We get a collection of all the types of nodes in the container (space newlines are text nodes)

2, get element child node — element collection

  • Grammar:[CONTAINER].children
  • Gets all element child nodes in the current container
  • Gets a collection of elements, with only element nodes
  • Only element tag, inIEComments are also treated as element nodes in older browsers

3. Obtain the parent node

  • Grammar:[NODE].parentNode
  • Gets the parent of a node

4, get a brother node

  • Grammar:[NODE].previousSibling
  • Gets the last sibling of a node

5, get a brother element node

  • Grammar:[NODE].previousElementSibling
  • Gets the last sibling element node of a node (not compatible with IE earlier versions)

6, get a brother node

  • Grammar:[CONTAINER].nextSibling
  • Gets the next sibling of a node

7, get a brother element node

  • Grammar:[CONTAINER].nextElementSibling
  • Gets the next sibling of a node (not compatible with earlier versions of IE)

8. Get the first child node

  • Grammar:[CONTAINER].firstChild
  • Gets the first child node in the container

Get the first element child node

  • Grammar:[CONTAINER].firstElementChild
  • Gets the first element child node in the container (incompatible with IE earlier versions)

Get the last byte point

  • Grammar:[CONTAINER].lastChild
  • Gets the last byte point in the container

Get the last element child node

  • Grammar:[CONTAINER].lastElementChild
  • Gets the child node of the last element in the container (incompatible with earlier versions of IE)

All methods and attributes are there to quickly get to the DOM element or node we want to manipulate

Mind mapping

Three, demand exercises

1. Encapsulate a method: Get all element child nodes in the specified CONTAINER, compatible with all browsers

function children(container) {
	// Get all the child nodes, iterate over them, and all the children of the element whose NODETYPE===1 are the ones we want
	var nodeList = container.childNodes,
		result = [];
	for (var i = 0; i < nodeList.length; i++) {
		var itemNode = nodeList[i];
		if (itemNode.nodeType === 1) {
			// Element noderesult.push(itemNode); }}return result;
}

var arr = children(box);
console.log(arr);
Copy the code

2. Get all element elder nodes of the current node (compatible with all browsers)

The prevAll method in JQ does just that, so we’ll wrap one of our own

Method one: Loop through the child node method of the current element’s parent

PreviousElementSibling: previousElementSibling: previousElementSibling: previousElementSibling: previousElementSibling: previousElementSibling: previousElementSibling: previousElementSibling:

function prevAll(node) {
	let result = [];
	// Get the parent
	let parent = node.parentNode;
	// Get his father's sons (himself and all his brothers)
	let nodeList = parent.childNodes;
	// Loop through all nodes, the element type is what we want, and the loop stops when we find the current node
	for (let i = 0; i < nodeList.length; i++) {
		let item = nodeList[i];
		if (item === node) {
			// Find yourself
			break;
		}
		// Store the element node instead of itself
		if (item.nodeType === 1) { result.push(item); }}return result;
}
Copy the code

Method 2: Obtain the elder node of the current node, and then obtain the elder node of the elder node… Find until there are no older siblings (NULL if there are no older siblings); In the process of searching again, store all found element nodes.

//=> loop does not know how many times => loop

function prevAll(node) {
	let prev = node.previousSibling,
		result = [];
	// Cycle to find his brother until there is no brother left
	while(prev ! = =null) {
		// Store the element nodes found in the elder brother
		if (prev.nodeType === 1) {
			result.unshift(prev);
		}
		prev = prev.previousSibling;
	}
	return result;
}
Copy the code

3, get all brother element nodes (compatible with all browsers)

So just like in the previous problem, let’s do the same thing with both methods

Method one:

function nextAll(node) {
	// Get all the sons of their father
	let nodeList = node.parentNode.childNodes,
		result = [];
	// Start the loop backwards from the last item
	for (let i = nodeList.length - 1; i >= 0; i--) {
		let item = nodeList[i];
		if (item === node) break;
		item.nodeType === 1 ? result.unshift(item) : null;
	}
	return result;
}
Copy the code

Method 2:

function nextAll(node) {
	let result = [],
		next = node.nextSibling;
	while(next ! = =null) {
		next.nodeType === 1 ? result.push(next) : null;
		next = next.nextSibling;
	}
	return result;
}
Copy the code

Get all sibling element nodes: all brothers + all brothers

Method one:

function siblings(node) {
	// All the sons must include me and my brothers
	let nodeList = node.parentNode.childNodes,
		result = [];
	// Walk through each node in turn, excluding non-elements and myself, and store the rest
	for (let i = 0; i < nodeList.length; i++) {
		let item = nodeList[i];
		if (item.nodeType === 1&& item ! == node) { result.push(item); }// The above if criterion can also be rewritten as the following
		// if (item.nodeType ! == 1 || item === node) {
		// continue;
		// }
		// result.push(item);
	}
	return result;
}
Copy the code

Method 2: Use the methods encapsulated in the above two questions

function siblings(node) {
	// Call two methods to get all brothers and all brothers, which is all brothers
	return prevAll(node).concat(nextAll(node));
}
Copy the code

5, get the index of the current node: his rank among all brothers

function index(node) {
	// It has several brothers, so its index is what
	return prevAll(node).length;
}
Copy the code