DOM node operations
DOM Node Operations
DOM (Document Object Model) is the programming interface for HTML and XML documents, representing documents as a node tree, allowing developers to dynamically access and manipulate page content through JavaScript. Node operations are one of the most fundamental and core skills in front-end development.
Node Types and Basic Concepts
The DOM tree consists of different types of nodes, including:
- Document Node: The root node of the entire document
- Element Node: HTML tags
- Text Node: Text content within elements
- Attribute Node: Attributes of elements
- Comment Node: HTML comments
// Get the document node
const documentNode = document;
// Get an element node
const elementNode = document.getElementById('example');
// Get a text node
const textNode = elementNode.firstChild;
// Get an attribute node
const attrNode = elementNode.getAttributeNode('id');
Node Query Methods
The DOM provides various methods for querying nodes:
Query by ID
const element = document.getElementById('header');
Query by Class Name
const elements = document.getElementsByClassName('menu-item');
Query by Tag Name
const divs = document.getElementsByTagName('div');
Query Using CSS Selectors
// Query a single element
const firstItem = document.querySelector('.list-item');
// Query multiple elements
const allItems = document.querySelectorAll('.list-item');
Node Creation and Addition
Create New Nodes
// Create an element node
const newDiv = document.createElement('div');
// Create a text node
const newText = document.createTextNode('Hello World');
// Create an attribute node
newDiv.setAttribute('id', 'new-div');
Add Nodes to the DOM
// Append to the end of a parent element
parentElement.appendChild(newDiv);
// Insert at a specific position
parentElement.insertBefore(newDiv, referenceElement);
// Replace an existing node
parentElement.replaceChild(newDiv, oldChild);
Node Modification Operations
Modify Content
// Modify text content
element.textContent = 'New text content';
// Modify HTML content
element.innerHTML = '<strong>Bold text</strong>';
// Modify attributes
element.setAttribute('class', 'active');
element.className = 'active'; // Alternative method
element.classList.add('active'); // More modern approach
Modify Styles
// Directly modify the style property
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
// Manipulate via classList
element.classList.add('highlight');
element.classList.remove('inactive');
element.classList.toggle('active');
Node Deletion Operations
Remove Nodes
// Remove a child node from its parent
parentElement.removeChild(childElement);
// Modern method
childElement.remove();
Clear Node Content
element.innerHTML = '';
// Or
while (element.firstChild) {
element.removeChild(element.firstChild);
}
Node Traversal and Relationships
Parent-Child Relationships
// Get the parent node
const parent = element.parentNode;
// Get all child nodes
const children = element.childNodes;
// Get the first/last child node
const firstChild = element.firstChild;
const lastChild = element.lastChild;
Sibling Relationships
// Get the previous sibling node
const prevSibling = element.previousSibling;
// Get the next sibling node
const nextSibling = element.nextSibling;
Advanced Node Operations
Clone Nodes
// Shallow clone (excludes child nodes)
const shallowClone = element.cloneNode(false);
// Deep clone (includes all child nodes)
const deepClone = element.cloneNode(true);
Document Fragments
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li);
}
document.getElementById('list').appendChild(fragment);
Custom Data Attributes
// Set data attribute
element.dataset.userId = '12345';
// Read data attribute
const userId = element.dataset.userId;
Performance Optimization Considerations
Frequent DOM operations can trigger browser repaints and reflows, impacting performance. Here are some optimization tips:
- Batch Operations: Use document fragments for bulk insertion
- Offline Operations: Remove elements from the DOM first, make modifications, then re-add them
- Cache Query Results: Avoid repeatedly querying the same DOM elements
- Use Event Delegation: Reduce the number of event listeners
// Bad practice
for (let i = 0; i < 100; i++) {
document.body.appendChild(document.createElement('div'));
}
// Good practice
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);
Practical Application Examples
Dynamic List Operations
// Add a list item
function addListItem(text) {
const list = document.getElementById('myList');
const li = document.createElement('li');
li.textContent = text;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.addEventListener('click', function() {
li.remove();
});
li.appendChild(deleteBtn);
list.appendChild(li);
}
// Usage example
addListItem('First item');
addListItem('Second item');
Dynamic Form Validation
const form = document.getElementById('signup-form');
const emailInput = document.getElementById('email');
emailInput.addEventListener('blur', function() {
const errorElement = document.getElementById('email-error') ||
document.createElement('div');
errorElement.id = 'email-error';
if (!this.value.includes('@')) {
errorElement.textContent = 'Please enter a valid email address';
errorElement.className = 'error-message';
this.parentNode.appendChild(errorElement);
} else {
if (errorElement.parentNode) {
errorElement.parentNode.removeChild(errorElement);
}
}
});
Modern DOM Operation APIs
classList API
const element = document.getElementById('myElement');
// Add classes
element.classList.add('active', 'highlight');
// Remove classes
element.classList.remove('inactive');
// Toggle classes
element.classList.toggle('visible');
// Check if a class exists
if (element.classList.contains('active')) {
// Perform action
}
MutationObserver
Used to monitor DOM changes:
const targetNode = document.getElementById('observable');
const config = {
attributes: true,
childList: true,
subtree: true
};
const callback = function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log('Child nodes changed');
} else if (mutation.type === 'attributes') {
console.log(`Attribute ${mutation.attributeName} changed`);
}
}
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
// Stop observing
// observer.disconnect();
Cross-Browser Compatibility
While modern browsers have fairly consistent support for DOM APIs, older browsers require special attention:
-
textContent vs innerText
textContent
gets all element content, including hidden elementsinnerText
considers CSS styles and does not return hidden element text
-
Event Handling Differences
- Modern browsers use
addEventListener
- Older IE versions use
attachEvent
- Modern browsers use
-
classList Compatibility
- IE10+ supports classList
- Older browsers require className manipulation
// Cross-browser class addition
function addClass(element, className) {
if (element.classList) {
element.classList.add(className);
} else {
element.className += ' ' + className;
}
}
// Cross-browser event listening
function addEvent(element, event, handler) {
if (element.addEventListener) {
element.addEventListener(event, handler);
} else if (element.attachEvent) {
element.attachEvent('on' + event, handler);
} else {
element['on' + event] = handler;
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn