Node access add, delete, modify and query
And get page element type, but node operation uses node level relationship to get elements
- Getting elements by parent-child sibling relationship
- Logical, but less compatible
- Generally, a node has at least three basic attributes: nodeType, nodeName and nodeValue
Node type
Node type | Explain | value |
---|---|---|
Element node | Each HTML tag is an element node, such as < div >, < p >, < UL >, etc | 1 |
Attribute node | Attributes of element nodes (HTML tags), such as id, class, name, etc. | 2 |
Text node | The text content in the element node or attribute node. | 3 |
Comment Nodes | Represents a document comment in the form of. | 8 |
Document node | Represents the entire document (root node of DOM tree, i.e. document) | 9 |
- In the actual development, the main operation of node operation is element node
Get node (level)
Using DOM tree, nodes can be divided into different types of hierarchical relationships, which are often * * parent-child hierarchical relationships**
1. Parent node
node.parentNode
- The parentNode property returns the parent node of a node. Note that it is the nearest parent node
- Returns null if the specified node does not have a parent
2. child nodes
1. parentNode.childNodes //standard
parentNode, childNodes returns the collection of child nodes containing the specified node, which is the collection of immediate updates.
Note: the return value contains all child nodes, including element nodes, text nodes, etc
If you only want to get the element nodes in it, you need to deal with them specially. So we generally do not advocate the use of child Nodes
//Using nodeType to extract element nodes var ul = document.querySelector ('ul'); for(var i= 0; i < ul.childNodeslength;i++) { if (ul.childNodes[i].nodeType === 1)( // u1. childNodes[i] are element nodes console. log(ul.childNodes[i]); }
[focus on this] get all child nodes
parentNode.children //Nonstandard
parentNode.children is a read-only attribute that returns all child element nodes. [key points]
Although children is a non-standard, it is supported by various browsers, so we can use it with confidence
3. First and last node
The first way to return the first node
1. parentNode.firstChild
Return to the last child node
2. parentNode.lastChild
- These two return node methods can not find return null, if found, it will return all child nodes, including text, comment nodes, etc
- In actual development, we don't want all nodes, just element nodes. What should we do? Look at the bottom.
The second way is to return the first element node
3. parentNode.firstElementChild
parentNode.firstElementChild returns the first child element node or null if it cannot be found
4. parentNode.lastElementChild
parentNode.lastElementChild returns the last child element node or null if it cannot be found
[but]: there are compatibility problems between the two methods. Only when IE9 is over, can it be supported. Don't worry, we have a third way A kind of
The third way is to get the compatibility of the first and last element nodes
Actual development method: no compatibility problem and return the desired element node
5. parentNode.children[0]; //Get the first element node
6. parentNode.children[parentNode.children.length - 1]; //Get the last element
Sub node small case (Sina navigation bar)
//Get ul box var nav = document.querySelector('.nav'); //Get 4 small li displayed var lis = nav.children; //Use a traversal to store the length of li, so as not to get every for loop var Len = lis.length; //for loop to register mouse events for(var i = 0; i < Len; i++) { lis[i].onmouseover = function(){ //a tag is the first element of li, and ul in li is the second element of li this.children[0].className = 'currentA'; this.children[1].style.display = 'block'; } lis[i].onmouseout = function(){ this.children[0].className = ''; this.children[1].style.display = 'none'; } }
4. Brother node
The first way
1. node.nextSibling
nextSibling returns the next sibling node of the current element, and null cannot be found. Also, it contains all nodes
2. node.previousSibling
previousSibling returns the last sibling node of the current element. null cannot be found. Also, it contains all nodes
These two silly methods are the same as the first method to get the first and last element methods, making people speechless
The second way
3. node.nextElementSibling
Nexterelementsibling returns the next sibling node of the current element, or null if not found
4. node.previousElementSibling
Nexterelementsibling returns the previous sibling node of the current element, or null if not found
There is also a compatibility issue with the previous second method that gets the first and last element methods. IE9 or above
Create node
document.createElemet('tagName')
- The document.createElement() method creates HTML elements specified by tagName, because these elements do not exist originally and are generated dynamically according to our requirements. All of them are also called dynamic element node
Insertion node
node.appendChild(child)
-
The node.appendChild() method adds a node to the end of the child list of the specified parent node, similar to the:: after pseudo element in css
-
**Disadvantages: * * if there are many contents in the element, you need to assign innerHTML value and append it to the parent element in appendChild(), which is troublesome
-
**Advanced syntax: * * use insertAdjacentHTML() to directly add string format elements to the parent element
node.insertBefore(child, specify element)
- The node.insertBefore() method adds a node to the front of the specified child node of the specified parent node, similar to the:: before pseudo element in css
Delete node
1. element.remove(); //It can also be deleted 2. node.removeChild(child); //Delete the parent node of the element node in the parent section
- The node.removeChild() method deletes a child node from the DOM and returns the deleted node
Case: (simple message board)
//Outermost box (get its child elements from this element)) var div = document.getElementsByClassName('box')[0]; //Textbox var txt = div.children[0]; //Release button var btn = div.children[1]; //ul get this element and add li tag var ul = div.lastElementChild; //Click events btn.onclick = function() { if(txt.value == '') { alert('You haven't entered yet..'); return false; } else { var li = document.createElement('li'); li.innerHTML = txt.value +"<a href = 'javascript:;'>delete</a>"; ul.insertBefore(li,ul.firstChild); txt.value = ''; //Delete elements var armove = li.firstElementChild; armove.onclick = function() { ul.removeChild(this.parentNode); } } }
Replication node (clone node)
node.colneNode();
-
The node.cloneNode() method returns a copy of the node that called the method, also known as the clone / copy node
-
[note] 1. If the bracket parameter is empty or false, it is a shallow copy, that is, only the node itself is cloned, not the child nodes in the element
-
2. If the bracket = = parameter is true, it is a deep copy, which copies the node itself and all its children
Case (dynamically generated table)
//Simulate preparing student data var datas = [{ name:'Wei Luo Luo', subject:'JavaScript', score:100 },{ name:'Hongli', subject:'JavaScript', score:98 },{ name:'Fu Heng', subject:'JavaScript', score:99 },{ name:'Ming Yu', subject:'JavaScript', score:88 },{ name:'Unfaithful man', subject:'JavaScript', score:0 }]; var tb = document.querySelector('tbody'); var len = datas.length; //Traversal array creation elements for(var i = 0; i < len; i++) { //Create row var tr = document.createElement('tr'); tb.appendChild(tr); //The number of td cells created in the row depends on the number of properties of the object, so you need to traverse the object data [i] for(var k in datas[i]) { //Creating Cells var td = document.createElement('td'); //Property value insert cell td.innerHTML = (datas[i][k]); //Insert row tr.appendChild(td); } //Create delete cell var td = document.createElement('td'); td.innerHTML = "<a href = 'javascript:;' title = 'Click Delete'>delete</a>"; tr.appendChild(td); } //The last step is to click the delete button to delete the data var close = document.getElementsByTagName('a'); var cloLen = close.length; for(var j = 0; j <cloLen; j++) { close[j].onclick = function() { tb.removeChild(this.parentNode.parentNode); } }
Three dynamic creation differences
- document.write()
document.write(<div>ss</div>); //The content of the original page may be overwritten, almost no need, just understand
- element.innerHTML
document.body.innerHTML(); //There's nothing in a hundred lines, but more than 100 lines will affect performance
- document.createElement()
document.createElement(); //Official recommendation
Difference:
-
document.write() directly writes content to the internal flow of the page, but when the document flow is completed, all pages will be redrawn [very serious, the original page will be lost]
-
innerHTML is to write content to a DOM node without causing the page to be redrawn
-
innerHTML is more efficient in creating multiple elements = = (don't splice strings, splice them in array form, strings are immutable, and splicing strings will also lead to slow efficiency) = =, slightly complex structure
-
createElement() is a little less efficient to create multiple elements, but the structure is clearer (create the element first, then append the content to the element)
[summary] in different browsers, innerHTML is more efficient than createElement (without string splicing)
Here are two kinds of innerHTML concatenated strings, using array and createElement efficiency comparison methods
// 1.innerHTML splicing character test (different computer hardware computing efficiency is different, here is the execution time of [Lenovo rescuer Y7000]: // 1 second) //The first is simpler. The following tests can also use this one <button>Click Add</button> var btn = document.querySelector('button'); btn.addEventListener('click',function() { consoloe.time(); for (var i = 0; i < 1000; i++) { document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>'; } consoloe.timeEnd(); }); //Second kinds function fn() { var d1 = +new Date(); var str = ''; for (var i = 0; i < 1000; i++) { document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>'; } var d2 = +new Date(); console.log(d2 - d1); } fn();
// 2.innerHTML array mode test (different computer hardware computing efficiency is different, here I am [Lenovo rescuer Y7000] execution time is about: // 4 ms, greatly reduced time) function fn() { var d1 = +new Date(); var array = []; for (var i = 0; i < 1000; i++) { array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>'); } document.body.innerHTML = array.join(''); var d2 = +new Date(); console.log(d2 - d1); } fn();
// 2.createElement array mode test (different computer hardware computing efficiency is different, here I am [Lenovo rescuer Y7000] execution time is about: // 13 milliseconds) function fn() { var d1 = +new Date(); for (var i = 0; i < 1000; i++) { var div = document.createElement('div'); div.style.width = '100px'; div.style.height = '2px'; div.style.border = '1px solid red'; document.body.appendChild(div); } var d2 = +new Date(); console.log(d2 - d1); } fn();
Node access compatibility writing
Advanced browser can get elements, text (including content, space, line feed), comments.
Low version browsers use the ability to get elements, text (no spaces, line breaks), comments.
How to get nodes and element nodes
Node / element node | Explain |
---|---|
node.parentNode | Last parent node |
parentNode.childNodes | All child nodes |
parentNode.children | All child element nodes [Key compatible] |
parentNode.firstChild | First child node |
parentNode...lastChild | Last child node |
parentNode.firstElementChild | First child element node [IE678 incompatible] |
parentNode.lastElementChild | Last child element node [IE678 incompatible] |
node.nextSibling | Next sibling node |
node.previousSibling | Last sibling node |
node.nextElementSibling | Next sibling element node [IE678 incompatible] |
node.previousSibling | Previous sibling element node [IE678 incompatible] |
Get first element node compatibility
var ul = document.getElementsByTagName('ul')[0]; // Concise method ul.children[0].style.background = 'orange'; // ① . compatibility encapsulation gets the first child element: function getFirstElementChild(ele) { if (ele.firstElementChild) { return ele.firstElementChild; } else { var node = ele.firstChild; while(node != null && node.nodeType != 1) { node = node.nextSibling; } // node == null or node.nodeType == 1 return node; } } var demo = getFirstElementChild(ul); console.log(demo); demo.style.background = 'pink';
Get last element node compatibility
var ul = document.getElementsByTagName('ul')[0]; //Concise writing ul.children[ul.children.length-1].style.background = 'lightblue' // Function encapsulation function getLastElementChild(ele) { if (ele.lastElementChild) { return ele.lastElementChild; } else { var nodeLast = ele.lastChild; while (nodeLast != null && nodeLast.nodeType != 1) { nodeLast = nodeLast.previousSibling; } return nodeLast; } } getLastElementChild(ul).style.background = '#008c8c';
Get previous element node compatibility
// ele.previousElementSibling displays undefined in IE678 var li2 = document.getElementById('#li2'); function getPreviousElement(ele) { // Capability testing if(ele.previousElementSibling) { // Google Firefox return ele.previousElementSibling; } else { // IE8 // Get previous node: null element text comment var node = ele.previousSibling; // Uncertain number of cycles // 1. node must exist, not null, 2. Node is not an element node while(node != null && node.nodeType != 1) { node = node.previousSibling } // node == null or node.nodeType == 1 return node; } } var li = getPreviousElement(li2); li.style.background = 'pink';
Get next element node compatibility
var li2 = document.getElementById('#li2'); //Compatibility encapsulation gets the last sibling element function getNextElement(ele) { if (ele.nextElementSibling) { return ele.nextElementSibling; } else { var nodeNext = ele.nextSibling; while (nodeNext != null && nodeNext.nodeType != 1) { nodeNext = nodeNext.nextSibling; } return nodeNext; } } getNextElement(li2).style.background = 'pink';