这是我参与 8 月更文挑战的第 9 天,活动详情查看: 8月更文挑战javascript
犹记得上回有一次面试的时候被问到 htmlCollection
和数组的关系。当时的我内心想的是, html
中的集合和数组的关系,那解题就是说 set
和数组的关系?html
因而……面试官当下当即纠正我, htmlCollection
是单词连在一块儿的,是 js
的一个内容。当时我多是想……找个地洞钻……java
不会的咋仍是得虚心接收,查漏补缺仍是比较合理。通过一系列的资料查询和总结以后,得出如下总结。node
下面开始进入本文的讲解~🙋面试
HTMLCollection
表示一个包含了元素(元素顺序为文档流中的接口)的集合(通用集合),还提供了从该集合中选择元素的属性和方法。getElementsByTagName()
方法返回的就是一个 HTMLCollection
对象。NodeList
对象是节点的集合。数组
经过如下方法,能够获取到 NodeList
对象。主要有:①在一些旧版本浏览器中的方法,好比 getElementsClassName()
方法,返回的是 NodeList
对象,而不是 HTMLCollection
对象。②全部浏览器的 Node.childNodes
属性返回的都是 NodeList
对象。③大部分浏览器的 document.querySelectorAll()
返回的是 NodeList
对象。浏览器
咱们能够经过如下代码进行验证:markdown
document.body.childNodes instanceof NodeList // true
document.querySelector('body') instanceof NodeList // true or false
document.getElementByClassName('body') instanceof NodeList // true or false
复制代码
HTMLCollection
对象中的属性和方法,举例两个:app
item(index)
—— 返回 HTMLCollection
中指定索引的元素,若是不存在则返回 null
;length
(只读) —— 返回 HTMLCollection
中元素的数量。接下来用一个例子来进行阐述验证。具体代码以下:函数
document.getElementsByTagName('body') instanceof HTMLCollection // true
const htmlCollection = document.getElementsByTagName('body')
console.log(htmlCollection.item(0)) // <body>...</body>
console.log(htmlCollection.length()) // 1
复制代码
NodeList
对象中的属性和方法主要有如下几种。包括:
item()
—— 返回某个元素基于文档数的索引;length()
—— 返回 NodeList
中的节点数量;NodeList.forEach()
—— 该方法用于遍历 NodeList
中的全部成员。它接收一个回调函数做为参数,每遍历一回就要执行这个回调函数一次,用法与数组实例的 forEach
方法是彻底一致的;NodeList.keys()/values()/entries()
—— 对于这三个方法来讲,它们都会返回一个 ES6
的遍历器对象,能够经过 for…of…
来进行循环遍历,以便于获取每个成员的信息。同时,须要注意以上三者的区别,分别以下:
咱们写点代码来论证以上内容。具体代码以下:
const nodelist = document.querySelectorAll('body')
console.log(nodelist.item(0)) // <body>...</body>
console.log(nodelist.length) // 1
console.log(nodelist.forEach(item => console.log(item))) // <body>...</body>
for(var key of nodelist.keys()) {
console.log(nodelist[key]) // <body>...</body>
}
for(var value of nodelist.values()) {
console.log(value) // <body>...</body>
}
for(var entry of nodelist.entries()) {
console.log(entry) // [0, body]
}
复制代码
HTMLCollection | NodeList | |
---|---|---|
集合 | 元素的集合 | 节点的集合 |
静态和动态 | HTMLCollection 是动态绑定的,是一个动态集合。DOM 树发生变化,HTMLCollection 也会随之变化,说明其节点的增删是敏感的 | NodeList 是一个静态集合,其不受 DOM 树元素变化的影响;至关因而 DOM 树、节点数量和类型的快照,也就是说对节点进行增删操做时,NodeList 是感受不到的。可是对节点内部内容修改,是能够感受获得的,好比修改 innerHTML |
节点 | 不包含属性节点和文本节点 | 只有 NodeList 对象有包含属性节点和文本节点 |
元素获取方式 | HTMLCollection 元素能够经过 name,id 或 index 索引来获取 | NodeList 只能经过 index 索引来获取 |
伪数组 | HTMLCollection 和 NodeList 都是类数组,不是数组,只是长得像数组而已。因此没法使用数组的方法,好比: pop(),push(),或 join() 等等 | 与 HTMLCollection 同样 |
在上述的表格中咱们能够了解到, HTMLCollection
是动态集合,当 DOM
树发生变化时, HTMLCollection
也会随之改变。而 NodeList
是静态集合,当 DOM
树发生变化时, NodeList
不会受到 DOM
树变化的影响。咱们来举两个例子进行阐述说明。
先附上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>htmlCollection和NodeList</title>
</head>
<body>
<ul>
<li></li>
<li></li>
<li>MondayLab</li>
<li></li>
<li></li>
</ul>
<script> var oldUl = document.querySelectorAll('ul')[0]; var oldLi = document.querySelectorAll('li'); console.log(oldUl); // NodeList[body] console.log(oldLi.length); // 5 var newLi = document.createElement('li'); oldUl.appendChild(newLi); console.log(oldLi.length); // 5 var length = oldLi.length - 1; oldLi[length].innerHTML = 'monday'; console.log(oldLi[length].innerHTML); // monday console.log(oldLi.length); // 5 → 虽然经过innerHTML能够读到文本节点的内容,可是长度依旧不变,仍是5 </script>
</body>
</html>
复制代码
你们能够看到,使用 querySelectorAll
来获取 <li>
,返回的是一个 NodeList
的集合。且当页面 DOM
结构发生改变时,其长度不会发生任何的改变。可是当改变 innerHTML
时,则文本节点的内容会发生改变。值得注意的是,即便 innerHTML
改变 DOM
的结构,但长度依旧是不变的,仍是 5
。
先附上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTMLCollection</title>
</head>
<body>
<ul>
<li></li>
<li></li>
<li>MondayLab</li>
<li></li>
<li></li>
</ul>
<script> var oldUl = document.getElementsByTagName('ul')[0]; var oldLi = document.getElementsByTagName('li'); console.log(oldUl); // HTMLCollection[body] console.log(oldLi.length); // 5 var newLi = document.createElement('li'); oldUl.appendChild(newLi); console.log(oldLi.length); // 6 → 顺利改变 DOM 的结构 </script>
</body>
</html>
复制代码
你们能够看到,使用 getElementByTagName
时,获取的是一个 HTMLCollection
集合,这个时候说明对节点进行增删操做时,页面的 DOM
结构会发生改变,且HTMLCollection
将实时地获取到集合的长度。
写到这里的时候,不得不感概 js
的 DOM
操做是如此的强大,也忽然就明白了本身以前写代码的时候为啥会遇到那么多坑。若是在学习之初就追溯于原理,可能跳的坑应该就能少不少了。
讲到这里,关于 HTMLCollection
和 NodeList
的内容就结束啦!但愿对你们有帮助~
彩蛋有几篇我看过还比较好理解的文章,有须要能够当扩展知识进行扩充哦~
lio_zero👉HTMLCollection和NodeList的区别
Snandy👉将HTMLCollection/NodeList/伪数组转换成数组
binyellow👉DOM操做,HTMLCollection、NodeList
关注公众号星期一研究室,第一时间关注优质文章,更多精选专栏待你解锁~
若是这篇文章对你有用,记得留个脚印jio再走哦~
以上就是本文的所有内容!咱们下期见!👋👋👋