一文彻底搞懂 DOM 元素获取:动态集合 vs 静态集合
一、前言
在日常开发中,我们经常需要获取页面中的元素,比如操作列表、监听事件、动态创建节点等。
但很多人容易忽略一个关键区别------有些 DOM 获取方法返回的是实时更新的集合(动态) ,而有些返回的是静态快照(静态) 。
理解这一点非常重要,否则你可能会遇到这样的坑:
"我用 querySelectorAll() 获取了所有 div,可新增一个后为什么长度没变?"
本文将带你彻底弄清楚这个问题。
二、DOM 元素获取方法总览
方法 | 返回类型 | 是否动态更新 | 常用性 | 说明 |
---|---|---|---|---|
getElementById() | Element | 否 | ⭐⭐⭐⭐ | 根据 id 获取单个元素 |
getElementsByTagName() | HTMLCollection | 是 | ⭐⭐⭐ | 按标签名获取多个元素 |
getElementsByClassName() | HTMLCollection | 是 | ⭐⭐⭐⭐ | 按类名获取多个元素 |
getElementsByName() | NodeList(动态) | 是 | ⭐⭐ | 按 name 属性获取表单项 |
querySelector() | Element | 否 | ⭐⭐⭐⭐⭐ | 返回第一个匹配的元素 |
querySelectorAll() | NodeList(静态) | 否 | ⭐⭐⭐⭐⭐ | 返回所有匹配的元素(不会自动更新) |
三、动态集合(Live Collection)
动态集合会在 DOM 结构发生变化(如新增、删除节点)时自动更新。
常见返回动态集合的方法:
- getElementsByTagName()
- getElementsByClassName()
- getElementsByName()
- element.children
示例:
xml
<ul id="list">
<li>内容1</li>
<li>内容2</li>
</ul>
<script>
const items = document.getElementsByTagName('li');
console.log(items.length); // 输出 2
const newLi = document.createElement('li');
newLi.textContent = '新内容';
list.appendChild(newLi);
console.log(items.length); // 输出 3(自动更新)
</script>
四、静态集合(Static Collection)
静态集合只在获取时"拍一张快照",之后即使 DOM 改变也不会更新。
常见返回静态集合的方法:
- querySelectorAll()
(querySelector() 返回单个元素,不涉及更新)
示例:
xml
<ul id="list">
<li>内容1</li>
<li>内容2</li>
</ul>
<script>
const items = document.querySelectorAll('li');
console.log(items.length); // 输出 2
const newLi = document.createElement('li');
newLi.textContent = '新内容';
list.appendChild(newLi);
console.log(items.length); // 仍是 2(不会变化)
</script>
五、开发实战建议
1. 记忆口诀
- "getElementsBy..." → 动态集合
- "querySelector..." → 静态快照
2. 常用方法推荐
场景 | 推荐方法 | 原因 |
---|---|---|
获取单个元素 | querySelector() | 支持复杂选择器(如 #app .btn ) |
批量获取并遍历 | querySelectorAll() | 简洁、易读 |
操作实时更新的列表 | getElementsByTagName() | 可自动响应 DOM 变化 |
表单元素操作 | getElementsByName() | 可通过 name 精确定位 |
六、动态 vs 静态实战对比
xml
<button id="add">添加元素</button>
<ul id="list">
<li>内容1</li>
<li>内容2</li>
</ul>
<script>
const liveList = document.getElementsByTagName('li'); // 动态集合
const staticList = document.querySelectorAll('li'); // 静态集合
document.querySelector('#add').addEventListener('click', () => {
const li = document.createElement('li');
li.textContent = '新内容';
list.appendChild(li);
console.log(`动态集合长度:${liveList.length}`);
console.log(`静态集合长度:${staticList.length}`);
});
</script>
点击按钮后:
- 动态集合长度会自动更新;
- 静态集合长度保持不变。
七、总结对比表
方法名 | 类型 | 动态/静态 | 常用性 | 说明 |
---|---|---|---|---|
getElementById | Element | 静态 | ⭐⭐⭐⭐ | 获取单个元素 |
getElementsByTagName | HTMLCollection | 动态 | ⭐⭐⭐ | 批量获取标签 |
getElementsByClassName | HTMLCollection | 动态 | ⭐⭐⭐⭐ | 批量获取类名 |
getElementsByName | NodeList(动态) | 动态 | ⭐⭐ | 表单专用 |
querySelector | Element | 静态 | ⭐⭐⭐⭐⭐ | 获取第一个匹配元素 |
querySelectorAll | NodeList(静态) | 静态 | ⭐⭐⭐⭐⭐ | 常用批量获取 |
element.children | HTMLCollection | 动态 | ⭐⭐⭐ | 获取子元素集合 |
八、结语
掌握这些细微的差别后,你就能更精准地操作 DOM,避免由于集合类型错误导致的逻辑问题。
一句话总结:
动态集合会自动更新,静态集合只取一次。