The Chinese name for DOM is 文档对象模型,and the English name is Document Object Model, which we abbreviate as DOM. It is an API for HTML and XML documents that presents HTML in a tree structure, allowing for a more intuitive study of the document structure. We refer to this tree-like document structure as the DOM tree or node tree, which is the same concept.
1. What is DOM?#
The Chinese name for DOM is 文档对象模型,and the English name is Document Object Model, which we abbreviate as DOM. It is an API for HTML and XML documents that presents HTML in a tree structure, allowing for a more intuitive study of the document structure. We refer to this tree-like document structure as the DOM tree or node tree, which is the same concept.
Through DOM nodes, JavaScript can modify the HTML tags, attributes, CSS styles, and specific content of the document, as well as respond to all events on the page.
2. Node Tree#
1. Node Types#
- Document Node - Document
- Element Node - Element
- Text Node - Text
- Comment Node - Comment
- Attribute Node - Attr
2. Attributes#
- Node Type - nodeType
- Node Name - nodeName
- Node Value - nodeValue
- Child Nodes - childNodes
- Parent Node - parentNodes
- Previous Node - previousSibling
- Next Node - nextSibling
- First Child Node - firstChild
- Last Child Node - lastChild
3. Document Node - document#
(1) Getting#
- getElementById() - Get element by ID
<div id="demo">Get element by ID</div>
<script>
var demo = document.getElementById('demo');
demo.onclick = function() {
console.log('Get element by ID')
}
</script>
<!-- Click the element with ID demo, console outputs 'Get element by ID' -->
- getElementsByName() - Get element by name
<input type="text" name="int" value="Get element by name 1">
<input type="text" name="int" value="Get element by name 2">
<script>
var int = document.getElementsByName('int');
for(var i = 0; i < int.length; i++) {
console.log(int[i].value);
}
</script>
<!-- Console outputs the value of elements with name int -->
- getElementsByTagName() - Get element by tag name
<div>Get element by tag name 1</div>
<div>Get element by tag name 2</div>
<script>
var div = document.getElementsByTagName('div');
for(var i = 0; i < div.length; i++) {
console.log(div[i].innerHTML)
}
</script>
<!-- Console outputs the text content of elements with tag name div -->
- getElementsByClassName() - Get element by class
<div class="demo">Get element by class 1</div>
<div class="demo">Get element by class 2</div>
<script>
var demo = document.getElementsByClassName('demo');
for(var i = 0; i < demo.length; i++) {
console.log(demo[i].innerHTML)
}
</script>
<!-- Console outputs the text content of elements with class demo -->
- querySelector() - Get element by selector
The querySelector() should be followed by symbols: class is written as .
, id is written as #
, tag is written directly as TagName
.
<div>Get tag name by selector</div>
<div class="div">Get class by selector</div>
<div id="div">Get id by selector</div>
<script>
var divtag = document.querySelector('div');
var divclass = document.querySelector('.div');
var divid = document.querySelector('#div');
divtag.onclick = function() {
console.log('Get tag name by selector')
};
// Click tag div, console outputs "Get tag name by selector"
divclass.onclick = function() {
console.log('Get class by selector')
};
// Click class div, console outputs "Get class by selector"
divid.onclick = function() {
console.log('Get id by selector')
};
// Click id div, console outputs "Get id by selector"
</script>
- querySelectorAll() - Get a collection of elements by selector
It returns an array collection.
<input type="text" value="int1">
<input type="text" value="int2">
<input type="text" value="int3">
<script>
var int = document.querySelectorAll('input')
for(i = 0; i < int.length; i++) {
console.log(int[i].value)
}
</script>
<!-- Browser prints out `int1`, `int2`, `int3` in sequence -->
(2) Creating#
- createElement() - Create element (tag) node
<ul id="ul"></ul>
<script>
var ul = document.getElementById('ul');
ul.appendChild(document.createElement('li'))
</script>
You can see that an li tag has been generated under ul.
- createTextNode() - Create text node
<ul id="ul"></ul>
<script>
var ul = document.getElementById('ul');
var li = ul.appendChild(document.createElement('li'));
var node = document.createTextNode('I am li');
li.appendChild(node);
</script>
A piece of text has been generated in the li tag.
- createAttribute() - Create attribute node
<input type="text">
<script>
var int = document.getElementsByTagName('input')[0];
var value = document.createAttribute('value');
value.nodeValue = 'Generated by creating attribute node';
int.setAttributeNode(value);
</script>
You can see that the value attribute has been successfully created.
- createComment() - Create comment node
<div id="div">Create a comment node</div>
<script>
var div = document.getElementById('div');
var comment = document.createComment('Add a comment node');
div.appendChild(comment);
</script>
Check the source code in F12, and you can see a line of comment generated in div.
- createDocumentFragment() - Create document fragment
The role of a document fragment is equivalent to the parent element of all nodes added.
- If there is no createDocumentFragment, adding many nodes can still be presented in the DOM, but each time an appendChild() method is called, it generates multiple page renderings, which appears bulky.
- By placing multiple nodes to be added inside a createDocumentFragment node, the page will only call once to render all nodes.
-
createEvent() - Create event object
-
addEventListener() - Add event listener function
-
removeEventListener() - Remove event listener function
Detailed explanation of event listener functions
- dispatchEvent() - Trigger event
Manipulating CSS#
<div id="demo">DOM</div>
<script>
// Directly manipulate style with '.'
var demo = document.getElementById('demo');
demo.style.color = 'red';
// Create attribute node using setAttribute()
demo.setAttribute('style', 'background-color: green');
// Using the cssText property of style
demo.style.cssText = "border: 10px solid black";
</script>
4. Element Node (Element Object)#
Differences between innerHTML, innerText, outerHTML, and outerText
One is element content, and the other is text content.
<div id="div1">First div</div>
<div id="div2">Second div</div>
<div id="div3">Third div</div>
<div id="div4">Fourth div</div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<script>
var div1 = document.getElementById('div1').innerHTML
console.log(div1) // First div
var div1 = document.getElementById('div1').outerHTML
console.log(div1) // <div id="div1">First div</div>
var div2 = document.getElementById('div2').innerText
console.log(div2) // Second div
var div2 = document.getElementById('div2').outerText
console.log(div2) // Second div
document.getElementById('div5').innerHTML = '<a>《Fifth div》</a>'
// Adds content within the existing tag, if there are tags they will be recognized
document.getElementById('div6').outerHTML = '<a>《Sixth div》</a>'
// The original tag will be replaced, if the new text contains tags they will be automatically generated, if not, it will be displayed as text
document.getElementById('div7').innerText = '<a>《Seventh div》</a>'
// Adds content within the existing tag, new tags will not be recognized as tag elements but will be written directly as text content within the original tag
document.getElementById('div8').outerText = '<a>《Eighth div》</a>'
// The original tag will be replaced, new tags will not be recognized as tag elements but will be displayed directly as text
</script>
(1) Node Properties#
- childElementCount - Returns the number of child nodes of the current element
<div id="demo">
<a></a>
<span></span>
<p></p>
<div></div>
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.childElementCount) // 4
</script>
- firstElementChild - Returns the first child element node of the current element
lastElementChild - Returns the last child element node of the current element
<div id="demo">
<a></a>
<span></span>
<p></p>
<div></div>
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.firstElementChild) // <a></a>
console.log(demo.lastElementChild) // <div></div>
</script>
- nextElementSibling - Returns the next sibling element node of the current element
previousElementSibling - Returns the previous sibling element node of the current element
<span></span>
<div id="demo"></div>
<p></p>
<script>
var demo = document.getElementById('demo')
console.log(demo.nextElementSibling) // <p></p>
console.log(demo.previousElementSibling) // <span></span>
</script>
- Returns all child nodes of the current element
<div id="demo">
<span></span>
<p></p>
<a></a>
</div>
<script>
var demo = document.getElementById('demo').children
for(var i in demo) {
console.log(demo[i])
}
</script>
Check the console for the returned result.
- Returns all child node collections
<div id="demo">
<span></span>
<p></p>
<a id="demo1"></a>
</div>
<script>
var demo = document.getElementById('demo').children
for(var i in demo1.childNodes) {
console.log(demo[i])
}
</script>
(2) Node Methods#
- appendChild - Insert child node
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('Insert a child node')
demo.appendChild(node)
</script>
You can see that a node has been inserted into the div.
- insertBefore(a, b) - Insert node at specified position
Parameter a represents the content to be inserted, b represents the position, inserting a node before b.
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('Insert a child node')
demo.appendChild(node)
var hr = document.createElement('hr')
demo.insertBefore(hr, node)
</script>
You can see that a new element node has been added before the original text node.
- replaceChild(a, b) - Replace node
Replace parameter b with parameter a, where a is the new node and b is the old node.
<div id="demo"></div>
<script>
var demo = document.getElementById('demo')
var node = document.createTextNode('Insert a child node')
demo.appendChild(node)
var h3 = document.createElement('h3')
var h3node = document.createTextNode('Title')
h3.appendChild(h3node)
demo.replaceChild(h3, node)
</script>
h3
is the new node, node
is the old node. As seen in the image, b replaces a, successfully taking its place.
- removeChild - Parent node removes child node
<div id="demo">
<div id="son"></div>
</div>
<script>
var demo = document.getElementById('demo')
var son = document.getElementById('son')
demo.removeChild(son)
</script>
You can see that the element node with id son has been deleted using demo.removeChild()
.
- removeAttribute - Remove attribute node
<div id="demo" class="div"></div>
<script>
var demo = document.getElementById('demo')
demo.removeAttribute('class')
</script>
The class attribute has been deleted.
- Delete text node
<div id="demo">Text</div>
<script>
var demo = document.getElementById('demo')
demo.removeChild(demo.childNodes[0])
</script>
By using demo.childNodes[0]
to get the first node of demo, which is the text node, and then removeChild
it, it has been deleted.
- isEqualNode - Determine if two elements are
equal
isSameNode - Determine if two elements arethe same
The two represent
equal
andthe same
respectively.
(1) isEqualNode
equal means whether the two nodes are of the same type, have equal attributes (including: nodeName, nodeValue... etc.), and have equal attributes, childNodes (the same position contains the same value).
(2) isSameNode
the same means that the two nodes reference the same object.
<form action="#">
<input type="button" />
</form>
<form action="#">
<input type="button" />
</form>
<form action="#" id="o">
<input type="button" />
</form>
<form action="#" id="o">
<input type="text" />
</form>
<script>
var forms = document.forms;
var form1 = forms[0];
var form2 = forms[1];
var form3 = forms[2];
var form4 = forms[3];
var _form1 = document.querySelectorAll('form')[0];
console.log(form1.isSameNode(form1)) //true Both nodes reference the first form
console.log(form1.isSameNode(_form1)) //true Both nodes reference the first form
console.log(form1.isSameNode(form2)) //false Both nodes do not reference the same object
console.log(form1.isEqualNode(form2)) //true Both nodes have completely equivalent attributes
console.log(form1.isEqualNode(form3)) //false form1 has no equivalent id attribute
console.log(form3.isEqualNode(form4)) //false The input in form4's childNodes is of type text, which is different from form3
</script>
From the example code, the differences can be seen:
(1) isSameNode
is only the same when referencing the same object, for example, calling the same object using two methods, and comparing these two methods, it is still that object, so they are the same.
(2) isEqualNode
compares whether two object element nodes are equal, as long as both are consistent, it can be equal true.
- hasChildNodes() - Determine if an element has child nodes
Determine whether demo
has child nodes, then output its child nodes.
<div id="demo">
<!-- <a></a> -->
</div>
<script>
var demo = document.getElementById('demo')
console.log(demo.hasChildNodes())
console.log(demo.childNodes)
</script>
- contains(a) - Determine if a node contains a specified child node (parameter a represents the child node to be checked)
There exists an element with id="a"
, so contains returns true.
There does not exist an element with id="b"
, so it returns false.
<div id="demo">
<a id="a"></a>
<a></a>
</div>
<script>
var demo = document.getElementById('demo')
var a = document.getElementById('a')
console.log(demo.contains(a)) // true
var b = document.getElementById('b')
console.log(demo.contains(b)) // false
</script>
5. Attribute Node (Attr Object)#
<input type="text" id="int">
<script>
var int = document.getElementById('int')
// 1. Get attribute value
console.log(int.getAttribute("type"))
// text
// 2. Get attribute node
console.log(int.getAttributeNode("type"))
// type="text"
// 3. Set attribute value
int.setAttribute("value", "Input box")
// <input type="text" id="int" value="Input box">
// 4. Set attribute node
let name = document.createAttribute("name");
name.nodeValue = "uname";
int.setAttributeNode(name);
console.log(int.getAttributeNode('name').value)
// <input type="text" id="int" value="Input box" name="uname">
// 5. Delete attribute node
console.log(int.removeAttribute('name'))
// <input type="text" id="int" value="Input box">
// 6. Check if attributes exist
console.log(int.hasAttributes())
// true
// 7. Check if a specific attribute exists
console.log(int.hasAttribute('value'))
// true
</script>
Note: The difference between
hasAttribute
andhasAttributes
hasAttributes
checks if attributes exist,
hasAttribute
checks if a specific attribute exists.