在前端开发中,我们经常需要操作 DOM 元素。当我们使用 document.querySelectorAll()
或者 element.querySelectorAll()
查询到一组元素时,得到的就是一个 NodeList 对象。
NodeList 是一个类数组对象(array-like object),它表示了一个包含零个或多个节点的列表,每个节点都有一个对应的整数索引。与真正的数组不同,NodeList 不能被修改(例如,你不能使用 push、pop 等方法)。但是,你可以通过索引访问其中的节点并使用 length 属性获取其长度。
NodeList 是否 live 还是 static
对于一个 NodeList 对象,它的 live 或者 static 特性取决于如何获取该对象。
Live NodeList
如果通过以下方式获取 NodeList 对象:
const nodeList = document.querySelectorAll('div');
那么这个 NodeList 就是 live 的。这意味着当文档结构发生变化时(例如增加、删除或者移动节点),NodeList 会自动更新,以反映出最新的文档结构。
例如,假设我们有以下 HTML 结构:
<body> <div></div> </body>
我们可以通过以下代码获取 NodeList:
const nodeList = document.querySelectorAll('div'); console.log(nodeList.length); // 输出 1
现在,在 JavaScript 中添加一个新的 div 元素:
const newDiv = document.createElement('div'); document.body.appendChild(newDiv);
再次查看 NodeList 的长度:
console.log(nodeList.length); // 输出 2
可以看到,NodeList 已经自动更新了,以反映出最新的文档结构。
Static NodeList
如果通过以下方式获取 NodeList 对象:
const nodeList = Array.from(document.querySelectorAll('div'));
那么这个 NodeList 就是 static 的。这意味着当文档结构发生变化时,NodeList 不会自动更新,仍然保持最初查询时的结果。
例如,假设我们有以下 HTML 结构:
<body> <div></div> </body>
我们可以通过以下代码获取 NodeList:
const nodeList = Array.from(document.querySelectorAll('div')); console.log(nodeList.length); // 输出 1
现在,在 JavaScript 中添加一个新的 div 元素:
const newDiv = document.createElement('div'); document.body.appendChild(newDiv);
再次查看 NodeList 的长度:
console.log(nodeList.length); // 仍然输出 1
可以看到,NodeList 没有更新以反映出最新的文档结构。
如何使用
对于 live 和 static 的 NodeList,我们可以使用相同的方法来访问其中的节点。例如,我们可以使用索引来访问其中的节点:
const nodeList = document.querySelectorAll('div'); const firstDiv = nodeList[0];
或者我们可以使用 forEach 方法迭代其中的每个节点:
const nodeList = document.querySelectorAll('div'); nodeList.forEach((div) => { console.log(div); });
需要注意的是,如果 NodeList 是 live 的,那么在迭代时,如果文档结构发生变化,可能会导致一些节点被跳过或者重复遍历。因此,最好在迭代之前将其转换成静态的数组:
const nodeList = document.querySelectorAll('div'); const divArray = Array.from(nodeList); divArray.forEach((div) => { console.log(div); });
总结
NodeList 是一个表示包含零个或多个节点的列表的类数组对象。它可以通过 document.querySelectorAll()
或者 element.querySelectorAll()
方法获取。对于不同的获取方式,NodeList 可能是 live 的或者 static 的,这取决于文档结构的变化是否会影响 NodeLIst 的内容。我们可以使用索引或者 forEach 方法访问其中的节点,并且可以通过将其转换成静态数组来解决 live NodeList 迭代时可能出现的问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/28129