banner
SlhwSR

SlhwSR

热爱技术的一名全栈开发者
github
bilibili

Explore the browser's DOM object in depth.

1. DOM#

The Document Object Model (DOM) is a programming interface for HTML and XML documents.

It provides a structured representation of the document and defines a way to access and modify the structure, style, and content of the document.

Any HTML or XML document can be represented as a hierarchical structure composed of nodes.

Nodes can be of different types, each corresponding to different information or markup in the document. They have their own attributes, data, and methods, and are related to other types of nodes, as shown below:

<html>
    <head>
        <title>Page</title>
    </head>
    <body>
        <p>Hello World!</p >
    </body>
</html>

DOM is like an atom containing subatomic particles, where different types of DOM nodes contain other types of nodes. Let's take a look at three of them:

<div>
    <p title="title">
        content
    </p >
</div>

In the above structure, div and p are element nodes, content is a text node, and title is an attribute node.

2. Manipulation#

In everyday front-end development, we cannot do without DOM manipulation.

In the past, we used libraries like jQuery and Zepto to manipulate the DOM. After the emergence of frameworks like Vue, Angular, and React, we started controlling the DOM by manipulating data (most of the time) and relied less on direct DOM manipulation.

However, this does not mean that native DOM manipulation is not important. On the contrary, DOM manipulation can help us understand the deeper aspects of frameworks.

Let's analyze the common operations of DOM manipulation, which can be mainly divided into:

  • Creating nodes
  • Querying nodes
  • Updating nodes
  • Adding nodes
  • Removing nodes

Creating Nodes#

createElement#

Creates a new element with the specified tag name.

const divEl = document.createElement("div");

createTextNode#

Creates a new text node.

const textEl = document.createTextNode("content");

createDocumentFragment#

Creates a new document fragment, which represents a lightweight document used to store temporary nodes. The content of the document fragment can be added to the DOM all at once.

const fragment = document.createDocumentFragment();

When inserting a DocumentFragment node into the document tree, it is not the DocumentFragment itself that is inserted, but all of its descendants.

createAttribute#

Creates an attribute node, which can be a custom attribute.

const dataAttribute = document.createAttribute('custom');
console.log(dataAttribute);

Querying Nodes#

querySelector#

Selects the first element that matches the specified CSS selector.

document.querySelector('.element')
document.querySelector('#element')
document.querySelector('div')
document.querySelector('[name="username"]')
document.querySelector('div + p > span')

If there is no element that matches the selector on the page, null is returned.

querySelectorAll#

Returns a list of all elements within the node's subtree that match the specified CSS selector. If there are no matches, an empty list is returned.

const notLive = document.querySelectorAll("p");

It is important to note that this method returns a static instance of NodeList, which is a static "snapshot" of the query results, rather than a "live" query.

There are also other methods for getting DOM elements, such as:

document.getElementById('id'); // Returns the element with the specified id.
document.getElementsByClassName('class'); // Returns a collection of elements with the specified class.
document.getElementsByTagName('tag'); // Returns a collection of elements with the specified tag name.
document.getElementsByName('name'); // Returns a collection of elements with the specified name.
document/element.querySelector('CSS selector'); // Returns the first element that matches the CSS selector.
document/element.querySelectorAll('CSS selector'); // Returns all elements that match the CSS selector.
document.documentElement; // Gets the HTML tag in the page.
document.body; // Gets the BODY tag in the page.
document.all['']; // Gets a collection of all element nodes in the page.

In addition, each DOM element has properties such as parentNode, childNodes, firstChild, lastChild, nextSibling, and previousSibling, as shown in the diagram below:

image

Updating Nodes#

innerHTML#

Allows modification of the text content of a DOM node or the entire subtree by using an HTML fragment.

// Get the <p id="p">...</p> element
var p = document.getElementById('p');
// Set the text to "ABC":
p.innerHTML = 'ABC'; // <p id="p">ABC</p>
// Set the HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// The internal structure of <p>...</p> has been modified

innerText, textContent#

Automatically encodes the string as HTML, ensuring that no HTML tags can be set.

// Get the <p id="p-id">...</p> element
var p = document.getElementById('p-id');
// Set the text:
p.innerText = '<script>alert("Hi")</script>';
// The HTML is automatically encoded, and a <script> node cannot be set:
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>

The difference between the two is that innerText does not return the text of hidden elements, while textContent returns all text.

style#

The style property of a DOM node corresponds to all CSS styles and can be directly accessed or modified. Use camel case for hyphenated properties.

// Get the <p id="p-id">...</p> element
const p = document.getElementById('p-id');
// Set the CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px'; // Camel case
p.style.paddingTop = '2em';

Adding Nodes#

innerHTML#

If the DOM node is empty, such as <div></div>, you can directly use innerHTML = '<span>child</span>' to modify the content of the DOM node, effectively adding a new DOM node.

If the DOM node is not empty, you cannot do this because innerHTML will replace all existing child nodes.

appendChild#

Appends a child node to the end of a parent node's list of children.

For example:

<!-- HTML structure -->
<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

Add a p element:

const js = document.getElementById('js');
js.innerHTML = "JavaScript";
const list = document.getElementById('list');
list.appendChild(js);

The HTML structure now becomes:

<!-- HTML structure -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
    <p id="js">JavaScript</p> <!-- Added element -->
</div>

In the above code, we first get the DOM element and then perform the append operation. The js node is already in the current document tree, so it will be removed from its original position first and then inserted into the new position.

If you want to dynamically add a new node, you need to create a new node first and then insert it at the specified position:

const list = document.getElementById('list');
const haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);

insertBefore#

Inserts a child node before a specified reference node.

Use it like this:

parentElement.insertBefore(newElement, referenceElement)

The child node will be inserted before the referenceElement.

setAttribute#

Adds an attribute node to the specified element. If the element already has the attribute, the attribute value is changed.

const div = document.getElementById('id');
div.setAttribute('class', 'white'); // First parameter is the attribute name, second parameter is the attribute value.

Removing Nodes#

To remove a node, you first need to get the node itself and its parent node, and then call the parent node's removeChild method to remove itself.

// Get the node to be removed:
const self = document.getElementById('to-be-removed');
// Get the parent node:
const parent = self.parentElement;
// Remove the node:
const removed = parent.removeChild(self);
removed === self; // true

After removal, the node is no longer in the document tree, but it still exists in memory and can be added to another position at any time.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.