DOM选择器

getElementById

getElementById通过元素ID获取单个元素。

基本用法

// HTML: <div id="app">东巴文</div>
const element = document.getElementById("app");
console.log(element);  // <div id="app">东巴文</div>

// 如果不存在,返回null
const notFound = document.getElementById("not-exist");
console.log(notFound);  // null

注意事项

// ID区分大小写
// <div id="App"></div>
document.getElementById("App");   // 找到
document.getElementById("app");   // null

// 只返回第一个匹配
// <div id="test"></div>
// <div id="test"></div>(不合法,但浏览器可能容错)
document.getElementById("test");  // 返回第一个

// 只能在document上调用
// element.getElementById("id");  // TypeError

性能特点

// getElementById是最快的选择方法
// 因为浏览器维护了ID索引

// 推荐用于已知ID的单元素获取
const header = document.getElementById("header");
const footer = document.getElementById("footer");

getElementsByTagName

getElementsByTagName通过标签名获取元素集合。

基本用法

// 获取所有div元素
const divs = document.getElementsByTagName("div");
console.log(divs.length);  // div元素数量

// 获取所有元素
const all = document.getElementsByTagName("*");
console.log(all.length);  // 页面所有元素数量

// 在特定元素下查找
const container = document.getElementById("container");
const paragraphs = container.getElementsByTagName("p");

HTMLCollection特点

const divs = document.getElementsByTagName("div");

// HTMLCollection是类数组对象
console.log(divs[0]);        // 第一个div
console.log(divs.item(0));   // 第一个div

// 实时更新
console.log(divs.length);  // 3
document.body.appendChild(document.createElement("div"));
console.log(divs.length);  // 4(自动更新)

// 遍历
for (let i = 0; i < divs.length; i++) {
    console.log(divs[i]);
}

// 转为数组
const divArray = Array.from(divs);
const divArray2 = [...divs];

常用标签选择

const forms = document.getElementsByTagName("form");
const images = document.getElementsByTagName("img");
const links = document.getElementsByTagName("a");
const scripts = document.getElementsByTagName("script");

getElementsByClassName

getElementsByClassName通过类名获取元素集合。

基本用法

// HTML: <div class="item active">东巴文</div>
const items = document.getElementsByClassName("item");
console.log(items.length);  // 类名为item的元素数量

// 多个类名(同时匹配)
const activeItems = document.getElementsByClassName("item active");

// 在特定元素下查找
const container = document.getElementById("container");
const itemsInContainer = container.getElementsByClassName("item");

实时更新

const items = document.getElementsByClassName("item");

console.log(items.length);  // 3

// 添加新元素
const newItem = document.createElement("div");
newItem.className = "item";
document.body.appendChild(newItem);

console.log(items.length);  // 4(实时更新)

// 移除元素
items[0].remove();
console.log(items.length);  // 3

类名匹配规则

// <div class="item active"></div>
// <div class="active item"></div>
// <div class="item active highlight"></div>

document.getElementsByClassName("item active");  // 匹配全部三个
document.getElementsByClassName("active item");  // 同样匹配全部三个
// 顺序不重要,只要同时包含这些类名

querySelector

querySelector使用CSS选择器获取第一个匹配元素。

基本用法

// 通过标签选择
const div = document.querySelector("div");

// 通过ID选择
const header = document.querySelector("#header");

// 通过类选择
const item = document.querySelector(".item");

// 组合选择
const special = document.querySelector("div.item.active");

// 在特定元素下查找
const container = document.querySelector("#container");
const firstItem = container.querySelector(".item");

CSS选择器语法

// 后代选择器
const item = document.querySelector("ul li");

// 子选择器
const directChild = document.querySelector("ul > li");

// 相邻兄弟选择器
const next = document.querySelector("h1 + p");

// 属性选择器
const input = document.querySelector("input[type='text']");
const dataAttr = document.querySelector("[data-id]");

// 伪类选择器
const first = document.querySelector("li:first-child");
const last = document.querySelector("li:last-child");
const nth = document.querySelector("li:nth-child(2)");

// 伪元素选择器(返回null,因为伪元素不是DOM节点)
const before = document.querySelector("div::before");  // null

返回值

// 返回第一个匹配元素
const element = document.querySelector(".item");

// 未找到返回null
const notFound = document.querySelector(".not-exist");
console.log(notFound);  // null

// 不是实时更新
const items = document.querySelector(".item");
document.body.appendChild(document.createElement("div")).className = "item";
// items仍然指向原来的元素

querySelectorAll

querySelectorAll使用CSS选择器获取所有匹配元素。

基本用法

// 获取所有匹配元素
const items = document.querySelectorAll(".item");
console.log(items.length);  // 匹配元素数量

// 各种选择器
const divs = document.querySelectorAll("div");
const activeItems = document.querySelectorAll(".item.active");
const inputs = document.querySelectorAll("input[type='text']");
const evenRows = document.querySelectorAll("tr:nth-child(even)");

NodeList特点

const items = document.querySelectorAll(".item");

// NodeList是类数组对象
console.log(items[0]);        // 第一个元素
console.log(items.item(0));   // 第一个元素

// 不是实时更新
console.log(items.length);  // 3
document.body.appendChild(document.createElement("div")).className = "item";
console.log(items.length);  // 3(不变)

// 遍历方法
items.forEach(item => console.log(item));

// 转为数组
const array = Array.from(items);
const array2 = [...items];

复杂选择器

// 多选择器
const elements = document.querySelectorAll("h1, h2, h3");

// 复杂组合
const complex = document.querySelectorAll(
    "div.container > ul.list li.item:not(.disabled)"
);

// 表单元素
const required = document.querySelectorAll("input:required");
const checked = document.querySelectorAll("input:checked");

选择器性能

性能对比

// 性能从高到低:
// 1. getElementById
// 2. getElementsByTagName / getElementsByClassName
// 3. querySelector / querySelectorAll

// 原因:
// - getElementById 直接通过ID索引查找
// - getElementsBy* 返回实时集合,按需查询
// - querySelector* 需要解析CSS选择器

性能优化建议

// 1. 缓存选择结果
const items = document.querySelectorAll(".item");
items.forEach(item => item.classList.add("processed"));

// 2. 缩小查找范围
const container = document.getElementById("container");
const items = container.querySelectorAll(".item");

// 3. 使用更具体的选择器
// 不推荐
const items = document.querySelectorAll("div");
// 推荐
const items = document.querySelectorAll(".specific-class");

// 4. 避免在循环中重复选择
// 不推荐
for (let i = 0; i < 100; i++) {
    document.querySelector(".item").textContent = i;
}

// 推荐
const item = document.querySelector(".item");
for (let i = 0; i < 100; i++) {
    item.textContent = i;
}

选择器方法对比

方法 返回类型 实时 性能 东巴文建议
getElementById Element - 最高 按ID获取
getElementsByTagName HTMLCollection 按标签名
getElementsByClassName HTMLCollection 按类名
querySelector Element 复杂选择
querySelectorAll NodeList 复杂选择

实际应用

表单元素选择

// 获取表单
const form = document.querySelector("#loginForm");

// 获取输入框
const username = form.querySelector("input[name='username']");
const password = form.querySelector("input[name='password']");

// 获取按钮
const submitBtn = form.querySelector("button[type='submit']");

// 获取选中的单选框
const selectedRadio = form.querySelector("input[name='gender']:checked");

// 获取选中的复选框
const checkedBoxes = form.querySelectorAll("input[type='checkbox']:checked");

列表操作

// 获取列表项
const list = document.querySelector("#list");
const items = list.querySelectorAll("li");

// 添加点击事件
items.forEach((item, index) => {
    item.addEventListener("click", () => {
        console.log(`点击了第${index + 1}项`);
    });
});

// 获取特定位置的项
const firstItem = list.querySelector("li:first-child");
const lastItem = list.querySelector("li:last-child");
const secondItem = list.querySelector("li:nth-child(2)");

动态内容选择

// 等待元素出现
function waitForElement(selector, timeout = 5000) {
    return new Promise((resolve, reject) => {
        const element = document.querySelector(selector);
        if (element) {
            resolve(element);
            return;
        }
        
        const observer = new MutationObserver(() => {
            const element = document.querySelector(selector);
            if (element) {
                observer.disconnect();
                resolve(element);
            }
        });
        
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
        
        setTimeout(() => {
            observer.disconnect();
            reject(new Error("元素未找到"));
        }, timeout);
    });
}

// 使用
waitForElement(".dynamic-content").then(element => {
    console.log("元素已加载", element);
});

下一步

掌握了DOM选择器后,让我们继续学习:

  1. DOM操作 - 学习DOM操作
  2. DOM属性与样式 - 学习属性与样式
  3. 表单操作 - 学习表单操作

东巴文(db-w.cn) - 让编程学习更简单

🎯 东巴文寄语:DOM选择器是操作页面的第一步,掌握各种选择器方法及其性能特点,能让你高效地获取页面元素。在实际开发中,根据场景选择最合适的方法。在 db-w.cn,我们帮你精通DOM操作!