DOM query methods
Overview of DOM Query Methods
DOM querying is the foundation of JavaScript operations on webpage elements, allowing retrieval of node objects in a document through selectors or traversal methods. Browsers provide various native APIs, and modern development often combines these with CSS selector syntax for efficient targeting.
document.getElementById()
Retrieves a single node by its ID attribute, returning the first matching DOM object. IDs should be unique within a document, making this one of the fastest query methods.
const header = document.getElementById('main-header');
header.style.color = '#ff0000';
Note: This method is case-sensitive and only searches from the document object.
document.getElementsByClassName()
Returns a collection (HTMLCollection) of all elements with the specified class name. The collection is dynamic and updates automatically with DOM changes.
const buttons = document.getElementsByClassName('action-btn');
for (let btn of buttons) {
btn.addEventListener('click', handleClick);
}
When the document structure changes, the HTMLCollection automatically reflects these changes. Converting it to an array can avoid performance issues:
const btnArray = Array.from(buttons);
document.getElementsByTagName()
Retrieves a collection of elements by tag name, supporting the wildcard "*" to get all elements. Returns a dynamic HTMLCollection.
const images = document.getElementsByTagName('img');
console.log(`Page contains ${images.length} images`);
document.querySelector()
Uses CSS selector syntax to return the first matching element, supporting complex selector combinations:
// Get the first li element with class "active"
const item = document.querySelector('li.active');
// Get elements with a data-target attribute
const target = document.querySelector('[data-target]');
document.querySelectorAll()
Returns a static NodeList of all matching elements, supporting full CSS selector syntax:
// Get all even-numbered table rows
const rows = document.querySelectorAll('tr:nth-child(even)');
// Compound selector example
const elements = document.querySelectorAll('.panel > .header, .tooltip');
Unlike HTMLCollection, NodeList does not update automatically but can be traversed using the forEach
method.
Special Collection Access
The document provides predefined collections for quick access to common elements:
document.links // All <a> and <area> elements
document.forms // All <form> elements
document.images // All <img> elements
document.scripts // All <script> elements
Node Relationship Queries
Relative queries using existing nodes:
const parent = element.parentNode;
const children = element.childNodes;
const firstChild = element.firstChild;
const lastChild = element.lastChild;
// Element-only traversal
const prevElement = element.previousElementSibling;
const nextElement = element.nextElementSibling;
Attribute Selector Queries
Precise matching using attribute selectors:
// Exact attribute value match
const exactMatch = document.querySelector('[type="submit"]');
// Contains specific string
const containsMatch = document.querySelector('[class*="btn-"]');
// Starts with
const startsWith = document.querySelector('[href^="https"]');
// Ends with
const endsWith = document.querySelector('[src$=".png"]');
Form Element Queries
Specialized query methods for form controls:
const form = document.forms['login-form'];
const emailInput = form.elements.email;
const radioButtons = form.elements['newsletter'];
Performance Optimization Tips
- Cache query results to avoid repeated queries:
// Bad practice
for(let i=0; i<100; i++) {
document.querySelector('.item').style.color = 'red';
}
// Recommended practice
const item = document.querySelector('.item');
for(let i=0; i<100; i++) {
item.style.color = 'red';
}
- Narrow the query scope:
// Query across the entire document
document.querySelectorAll('.item');
// More efficient query within a specific container
const container = document.getElementById('app');
container.querySelectorAll('.item');
- Prefer ID selectors, followed by class selectors.
Dynamic Filtering Techniques
Combine array methods for secondary processing of query results:
// Get all visible input fields
const inputs = Array.from(document.querySelectorAll('input'))
.filter(input => input.offsetParent !== null);
// Get elements with data- attributes
const dataElements = [...document.querySelectorAll('[data-]')];
Real-Time Observation Techniques
Monitor DOM changes using MutationObserver:
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.addedNodes.length) {
console.log('New nodes:', mutation.addedNodes);
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
Browser Compatibility Solutions
Handle compatibility issues for older browsers:
// Query function compatible with IE8
function query(selector) {
return document.querySelectorAll ?
document.querySelectorAll(selector) :
document.getElementById(selector.slice(1));
}
// Class name query compatibility solution
function byClass(className, context) {
context = context || document;
if (context.getElementsByClassName) {
return context.getElementsByClassName(className);
}
var elements = context.getElementsByTagName('*'),
result = [];
for (var i=0; i<elements.length; i++) {
if (elements[i].className.indexOf(className) != -1) {
result.push(elements[i]);
}
}
return result;
}
Complex Selector Examples
Demonstrate the power of CSS3 selectors:
// Get elements with attributes containing specific values
const langs = document.querySelectorAll('[lang|="en"]');
// Structural pseudo-class selectors
const thirdItem = document.querySelector('ul.items li:nth-child(3)');
// Negation pseudo-class
const nonHidden = document.querySelectorAll('div:not(.hidden)');
// State pseudo-classes
const checkedItems = document.querySelectorAll('input[type="checkbox"]:checked');
Custom Data Attribute Queries
Query components using data-* attributes:
// Get all carousel slides
const slides = document.querySelectorAll('[data-carousel="slide"]');
// Get elements with specific data values
const currentSlide = document.querySelector('[data-index="3"]');
Shadow DOM Queries
Query content within shadow DOM in web components:
const host = document.querySelector('custom-element');
const shadowInput = host.shadowRoot.querySelector('input');
Handling Dynamically Loaded Content
Query strategies for asynchronously loaded content:
// Use event delegation for dynamic content
document.addEventListener('click', function(e) {
if (e.target.matches('.dynamic-item')) {
console.log('Clicked dynamically loaded item');
}
});
// Check if an element exists
function waitForElement(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(() => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelector(selector));
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
Selector Performance Comparison
Performance differences between selectors:
// Faster selectors
document.getElementById('content');
document.getElementsByClassName('active')[0];
// Slower complex selectors
document.querySelector('div#content ul li.active > a[href^="#"]');
Error Handling Mechanisms
Robust query error handling:
function safeQuery(selector, parent = document) {
try {
const el = parent.querySelector(selector);
if (!el) throw new Error(`Element not found: ${selector}`);
return el;
} catch (error) {
console.error('Query error:', error);
return null;
}
}
const element = safeQuery('.missing-element') || document.createElement('div');
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn