preface
Simple notes, nothing more ⚠️ ⚠️
Types of nodes
The node type
There are 12 node types. The nodeType can be obtained by nodeType and is expressed in numbers 1 to 12
- NodeType: indicates the nodeType
- NodeName, depending on the node type. For elements of type Element, nodeName equals the tag name
- NodeValue, depending on the node type, is null for elements of type Element
Relationship between nodes
- The childNodes property, which contains an array object of class NodeList. NodeList can be accessed directly using the brackets NodeList[0], nodelist.item (1). Array.from is converted to an Array object
- The parentNode property points to the parentNode
- PreviousSibling, the preceding sibling of the first is null,
- NextSibling, the nextSibling, the nextSibling of the last is null,
- FirstChild, the firstChild
- LastChild, the lastChild
- HasChildNodes (), returns true if there are child nodes
Manipulation of the node
- Parentnode.appendchild () adds an element to the end of the childNodes list and returns the new element. If it is an existing element, the current node is moved.
- Parentnode. iertBefore(insert node, reference node), if the reference node is null, the last node will be inserted. If the reference node is firstChild, the first node is entered.
- Parentnode. replaceChild(Replace node, reference node)
- Parentnode.removechild (Deleted node)
- CloneNode (Boolean), Boolean passing false copies only the current node, Boolean passing true copies the current node and its children. CloneNode does not copy properties added by JS, such as event handlers.
- Normalize: Normalizes text nodes
The Document type
Document object Document is an instance of HTMLDocument (HTMLDocument inherits Document), representing the entire HTML page. Document is an attribute of the Window object and is therefore a global object. The nodeType of Document is 9
Document child node
-
Document.documentelement, which returns an HTML element
-
Document.childnodes [0], which returns an HTML element
-
Body property, which returns the body element
-
Doctype property, return
-
Title, the text that contains the label
-
URL, the complete URL of the current page
-
Domain, the domain name of the current page, can be changed, but only once
-
Referrer, the source of the page
💡 document.domain can be modified, but the modification is limited. For example, www.baidu.com can be modified to image.baidu.com.
💡 When a page nested with an iframe, you can modify the domain properties of the iframe, and when two documents have the same domain properties, you can share javascript objects.
Positioning elements
- getElementById
- GetElementsByTagName, which returns an HTMLCollection array object
- HTMLCollection object namedItem method, can be specified according to the node name, the element
- Document. GetElementsByTagName (‘ * ‘), will return all elements
- GetElementsByName, gets the element with the specified name
- Document. images, which gets all the image elements
- Document.links gets all the A tags that have the href attribute
- Document. forms, which gets all the form elements
const images = document.getElementsByTagName('img')
// Get the image whose name is t1
images.namedItem('t1')
Copy the code
Document writing
- Write: writes text
- Writeln, writes text and wraps
- Open, open a webpage
- Close, close the page
write
- Write If executed after OLOad, the write method overwrites the entire page.
- Write If executed after oload, the write method is written after the current script. The write in writing
script
After the tag,
Element type
NodeType of Element is 1, nodeName is the label name, and nodeValue is null.
NodeName and tagName return the same value, but tagName usually returns the upper case of the tagName
HTML
All HTML elements are of type HTMLElement, which inherits from the Element type and adds some attributes of its own.
Common attributes:
- id
- Title, additional information
- Dir, writing direction
- className
Attribute method
- GetAttribute: Gets the attribute. The attribute name is case insensitive, and ID is the same as ID.
- SetAttribute (key, value) : Sets the attribute. The attribute name is automatically lowercase
- RemoveAttribute, remove the attribute, not just the value. Deletes key and value
The attributes property
The Attributes attribute contains a NamedNodeMap instance, where each attribute of an element is stored.
- GetNamedItem (name) returns the node in the NamedNodeMap instance whose attribute is name
- RemoveNamedItem (name) removes the object whose attribute is name
- SetNamedItem (node) sets the attribute node
// id1 is the same as id2
const id1 = element.attributes.getNamedItem("id").nodeValue;
const id2 = element.attributes["id"].nodeValue;
// Delete attributes
element.attributes.removeNamedItem("id")
// Set the properties
const node = document.createAttribute("class");
node.value = "democlass";
element.attributes.setNamedItem(node);
// You can modify the property value directly
element.attributes["id"].nodeValue = "someOtherId";
Copy the code
Create the element
- Document.createelement () creates the element
The Text type
NodeType = 3, nodeValue = text, nodeName = #text, no child nodes are supported. ParentNode is the Element object. Once a reference to a text node is obtained, it can be modified directly via nodeValue
const textNode = document.getElementsByClassName('color_h1') [0]
textNode.firstChild.nodeValue = 'Hello'
// Or modify the data property to have the same effect as the nodeValue
textNode.firstChild.data = 'Hello'
Copy the code
Creating a text node
- document.createTextNode()
let element = document.createElement("div");
element.className = "message";
// Create a text node and insert it into the element
let textNode1 = document.createTextNode("Hello");
element.appendChild(textNode1);
// Multiple text nodes can be inserted
let textNode2 = document.createTextNode("World!");
element.appendChild(textNode2);
document.body.appendChild(element);
Copy the code
Normalized text node
Calling the Normalize method on an element containing multiple text nodes merges the text nodes into a single text node
let element = document.createElement("div");
element.className = "message";
// Create a text node and insert it into the element
let textNode1 = document.createTextNode("Hello");
element.appendChild(textNode1);
// Multiple text nodes can be inserted
let textNode2 = document.createTextNode("World!");
element.appendChild(textNode2);
// Text nodes will be merged
element.normalize()
Copy the code
The Comment type
Comment nodeType, nodeType is 8, nodeValue is the comment content, nodeName value is #comment”, parentNode is Document or Element and child nodes are not supported
// <div id="test"><! - comments -- > < / div >
let element = document.getElementById("test");
// Comment the node
let comment = div.firstChild;
// Comment out the contents of the node
console.log(comment.data)
console.log(comment.nodeValue)
Copy the code
Creating a comment node
- document.createComment()
CDATASection type
NodeType = 4.
DocumentType type
NodeType is equal to 10, which does not support dynamic creation. ParentNode is equal to the Docuemtn object, and DocumentType can be obtained using Document.docType.
- Name, the document type name,
<! DOCTYPE
The rest
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<script>
// html
console.log(document.doctype.name)
</script>
</body>
</html>
Copy the code
DocumentFragment type
DocumentFragment, nodeType = 11. DocumentFragment can be understood as a repository. DocumentFragment stores all nodes to be added to the document
Creating a document fragment
- document.createDocumentFragment
use
// If you do not use the document fragment, the browser will render 3 times
let ul = document.getElementById("myList");
for (let i = 0; i < 3; ++i) {
let li = document.createElement("li");
li.appendChild(document.createTextNode(`Item ${i + 1}`));
ul.appendChild(fragment);
}
// After using a document fragment, the browser will render it only once
let fragment = document.createDocumentFragment();
let ul = document.getElementById("myList");
for (let i = 0; i < 3; ++i) {
let li = document.createElement("li");
li.appendChild(document.createTextNode(`Item ${i + 1}`));
fragment.appendChild(li);
}
ul.appendChild(fragment);
Copy the code
Attr type
The Attr node resides on the attributes attribute of the element. NodeType is equal to 2, nodeName is equal to the attribute name, and nodeValue is equal to the attribute value. The Attr type is a node but not part of the DOM tree
// The name of attr is align
let attr = document.createAttribute("align");
// The value of attr is left
attr.value = "left";
// Set attributes for the element
element.setAttributeNode(attr);
Copy the code
DOM programming
Dynamic script
Dynamically inserted inline scripts are not executed if the script is inserted with innerHTML. Nodes can only be inserted through apis like appendChild, DOM, etc.
const script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(code));
// Can be executed
document.body.appendChild(script)
// Script cannot be executed
document.body.innerHTML = script
Copy the code
Dynamic style
function loadStyleString(css){
let style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode(css));
let head = document.getElementsByTagName("head") [0];
head.appendChild(style);
}
Copy the code
NodeList
NodeList is similar to HTMLCollection, but HTMLCollection objects have an additional namedItem method that can be referenced by the element’s name
MutationObserver
MutationObserver, which allows you to view an entire document, or a part of the DOM, or an element. Callback is triggered asynchronously when changes occur
The basic use
// Mo does not associate any DOM objects. Instead, it needs to use an observer
// Associate specific DOM objects with properties that already need to be observed
const mo = new MutationObserver(() = > {
console.log('dom change')})// Observe changes to the document.body element and attributes. When the body property changes, the callback in MutationObserver is triggered
// But a change in the document.body child, or in other docuemnt.body contents, does not trigger callback,
mo.observer(document.body, {
attributes: true
})
Copy the code
MutationRecord array
The MutationRecord array records a set of information that a callback might have been triggered by more than one operation. Each message contains what changes have taken place, what elements have been affected, etc.
const div = document.getElementById('id1');
const mo = new MutationObserver((MRecord) = > {
// Print the following result
console.log(MRecord);
});
mo.observe(div, {
attributes: true}); div.dataset.name ='World! ';
Copy the code
Multiple changes to the MutationRecord array will have multiple contents
const div = document.getElementById('id1');
const mo = new MutationObserver((MRecord) = > {
console.log(MRecord);
});
mo.observe(div, {
attributes: true}); div.dataset.name ='World! ';
div.dataset.name = 'Hello World! ';
Copy the code
callback
The first argument to callback is an array of MutationRecord and the second argument is an instance of MutationObserver
Disconnect method
Calling the Disconnect method stops listening for the callback.
// Stop listening for callbacks
mo.disconnect()
Copy the code
MutationObserver reuse
Call the observe method multiple times to observe multiple nodes.
const div1 = document.getElementById('id1');
const div2 = document.getElementById('id2');
const mo = new MutationObserver((MRecord) = > {
console.log(MRecord);
});
mo.observe(div1, {
attributes: true}); mo.observe(div2, {attributes: true}); div1.dataset.name ='1';
div2.dataset.name = '2';
Copy the code
MutationObserver reuse
Calling Disconnect does not terminate the MutationObserver instance, we can re-invoke Observe and continue to use it
const div1 = document.getElementById('id1');
const div2 = document.getElementById('id2');
const mo = new MutationObserver((MRecord) = > {
// The MRecord array has only one content
console.log(MRecord);
});
mo.observe(div1, {
attributes: true}); div1.dataset.name ='1';
mo.disconnect();
mo.observe(div2, {
attributes: true}); div2.dataset.name ='2';
Copy the code
MutationObserverInit with observation scope
MutationObserver can observe changes in attributes, changes in child nodes, and changes in text
- Subtree, Boolean, whether to observe children
- Attributes, Boolean, whether to view attributes
- AttributeFilter, string[], looks specifically at changes in those attributes
- AttributeOldValue, Boolean, whether the previous attribute value is recorded in the MutationRecord array.
- CharacterData, Boolean, whether to observe changes to modify characterData (text node, comment node)
- CharacterDataOldValue, Boolean, Whether the previous character value is recorded in the MutationRecord array.
- ChildList, Boolean, changes whether child nodes trigger observation
Subtree, set to true, observes the entire subnumber. If you remove the offspring from the subtree, if you modify it outside the original subtree, it still triggers the change.
ChildList, set to true, looks only at first-level subtrees
Asynchronous callback and record queue
Each change is recorded in the MutationRecord instance and added to the record queue, which is unique to each MutationObserver instance. Each time a MutationRecord is added to the queue, the previously registered callback is triggered if the current microtask queue length is 0.
takeRecords
Empty the queue and return the contents of the queue. It also stops callback listening
// Console is not triggered
let observer = new MutationObserver((mutationRecords) = > console.log(mutationRecords));
observer.observe(document.body, { attributes: true });
document.body.className = 'foo';
document.body.className = 'bar';
document.body.className = 'baz';
// [MutationRecord, MutationRecord, MutationRecord]
console.log(observer.takeRecords());
/ / []
console.log(observer.takeRecords());
Copy the code
Performance, memory, and garbage collection
The MutationObserver is a weak reference to the target DOM. If the target node is garbage collected, the MutationObserver does not block the collection.
The target node is a strong reference to the MutationObserver, and if the target node is reclaimed, the MutationObserver is reclaimed as well.
The MutationRecord instance prevents the node from being garbage collected. You can extract useful information from a MutationRecord, save it to a new object, and finally discard the MutationRecord.
reference
- Mutation Observers—subtree