XML DOM 节点列表(NodeList)最全速查表
—— 99% 的遍历、取值、坑全在这里,一张表吃透!
| 项目 | NodeList(querySelectorAll 返回) | HTMLCollection(getElementsByTagName 返回) | 关键区别 & 推荐 |
|---|---|---|---|
| 是否“活的”(live) | 否(静态,快照) | 是(实时更新) | 现代项目推荐 NodeList |
| 获取方式 | querySelectorAll() | getElementsByTagName()、children | querySelectorAll 完胜 |
| 是否可以用 for…of | 可以 | 可以 | 都行 |
| 是否有 length | 有 | 有 | 都行 |
| 是否能 .forEach() | 可以(原生支持) | 不行(老浏览器要借用 Array.prototype) | NodeList 胜! |
| 能否直接 [0] 取元素 | 可以 | 可以 | 都行 |
| 能否用扩展运算符 … | 可以 | 可以 | 都行 |
2025 年最推荐的 5 种写法(直接背)
const doc = new DOMParser().parseFromString(xmlStr, "text/xml");
const root = doc.documentElement;
// 1. 现代首选(99% 项目都用这个)
const books = root.querySelectorAll("book"); // 返回静态 NodeList
// 2. 遍历方式(任选其一)
books.forEach(book => { ... }); // 最优雅
for (const book of books) { ... } // 最直观
[...books].map(book => { ... }) // 想用 map/filter
// 3. 取第 N 个(两种都行)
const firstBook = books[0];
const lastBook = books.at(-1); // 2022+ 新特性,超好用
// 4. 老项目还在用的“活集合”(了解即可)
const booksLive = root.getElementsByTagName("book"); // HTMLCollection,实时更新
经典真实示例(全程用这个 XML)
<bookstore>
<book id="1" category="编程"><title>JS高级</title></book>
<book id="2" category="科幻"><title>三体</title></book>
</bookstore>
// 推荐写法(2025 标准)
const books = root.querySelectorAll("book");
// 需求1:打印所有书名
books.forEach(book => {
const title = book.querySelector("title")?.textContent;
console.log(title);
});
// 需求2:找出所有科幻书
const sciFiBooks = [...books].filter(book =>
book.getAttribute("category") === "科幻"
);
// 需求3:给每本书加一个 data-index 属性
books.forEach((book, index) => {
book.setAttribute("data-index", index);
});
// 注意:上面这句对 NodeList 完全有效!
// 如果你用的是 getElementsByTagName(活集合),后面再动态添加 <book> 也会自动出现在 books 中
// 需求4:只取前 3 本(静态优势体现)
const top3 = [...books].slice(0, 3);
常见坑 & 解决方案(必看)
| 坑 | 错误写法 | 正确写法(2025) |
|---|---|---|
| 想用 forEach 但报错 | getElementsByTagName("book").forEach | querySelectorAll("book").forEach |
| 想 filter 但不能直接用 | books.filter(...) | [...books].filter(...) 或 Array.from(books).filter(...) |
| 想取最后一个却写 -1 报错 | books[books.length-1] | books.at(-1)(推荐) |
| 动态添加节点后想立刻遍历新集合 | 用 querySelectorAll(不会更新) | 用 getElementsByTagName(活的)或重新查询 |
| 想一次性取多个不同标签 | 只能分两次查询 | querySelectorAll("book, author, title") |
一句话总结(背下来就无敌)
| 场景 | 永远选这个写法 |
|---|---|
| 99% 日常项目 | querySelectorAll() → NodeList |
| 需要实时响应 DOM 变化(极少) | getElementsByTagName() → HTMLCollection |
| 想用 forEach / map / filter | 必须用 querySelectorAll |
记住:2025 年以后,所有新项目写 XML DOM 遍历,一律 querySelectorAll + forEach 就够了!
需要我给你一个“NodeList vs HTMLCollection 实时对比演示网页”,随时说一声~