DOM 元素
操作页面之前,第一件事是选中元素——告诉 JavaScript"我要操作哪个标签"。DOM 提供了一系列查找方法:按 id、按标签名或类名、按 CSS 选择器。这一节把它们讲全,并说清各自的区别与适用场景。
按 id 查找:getElementById
id 在页面中唯一,因此返回单个元素;找不到时返回 null:
const box = document.getElementById("box"); // 找到 <div id="box">
console.log(box.tagName); // 输出:DIV
按标签名或类名查找
getElementsByTagName 与 getElementsByClassName 返回 HTMLCollection(类数组,实时反映页面变化),没有匹配项时长度为 0:
<p class="item">一</p>
<p class="item">二</p>
<script>
const items = document.getElementsByClassName("item");
console.log(items.length); // 输出:2
console.log(items[0].innerHTML); // 输出:一(按下标访问)
</script>
按 CSS 选择器:querySelector
querySelector 返回第一个匹配 CSS 选择器的元素;querySelectorAll 返回所有匹配项的 NodeList。写法与 CSS 完全一致,最灵活:
document.querySelector("#box"); // id 选择器,等价 getElementById
document.querySelector(".item"); // 第一个 .item
document.querySelectorAll("p.item"); // 所有 class="item" 的 <p>
document.querySelector("ul > li:first-child"); // 后代选择器、伪类都支持
HTMLCollection 与 NodeList 的区别
- HTMLCollection:实时(live)集合,页面变化会自动更新;只能按下标或 item() 访问。
- querySelectorAll 返回的 NodeList 是静态快照;多数现代环境支持 forEach,但严谨起见可先转成数组再遍历:
const list = document.querySelectorAll("p.item");
// NodeList 转数组后遍历,兼容性最好
[...list].forEach(p => console.log(p.innerHTML));
// 输出:一
// 输出:二
(示例 HTML:<p class="item">一</p><p class="item">二</p>。)
在元素间移动:节点关系
找到起点后,可用父子、兄弟关系在节点树中"走动":
const p = document.getElementById("demo");
p.parentNode; // 父节点
p.children; // 所有元素子节点(HTMLCollection)
p.firstElementChild; // 第一个元素子节点(推荐)
p.nextElementSibling; // 下一个兄弟元素
p.previousElementSibling; // 上一个兄弟元素
带 Element 的版本会跳过文本与注释节点,日常遍历元素用它更省心。
遍历集合的正确姿势
集合是类数组而非真数组,推荐转成数组或直接用 for 循环:
const ps = document.getElementsByTagName("p");
for (let i = 0; i < ps.length; i++) {
console.log("第" + i + "个:" + ps[i].innerHTML);
}
// 输出:第0个:一
// 输出:第1个:二
(配合上文两个 <p class="item"> 的页面运行。)
小结
选中元素有两条主线:单个精准定位用 getElementById 或 querySelector;批量处理用 getElementsByTagName/ClassName 或 querySelectorAll;再配合 parentNode、children 等关系属性在树中移动,配合集合遍历,就能定位页面上的任意元素。