DOM是JavaScript重要组成部分,在DOM中有三个特别的集合分别是 NodeList(节点的集合),NamedNodeMap(元素属性的集合)和HTMLCollection(html元素的集合) 。这三个集合有一些共同的特点:它们都是一个类数组对象,可以通过中括号表达式来访问集合中元素,也有length属性。但它们并不是数组,而且它们都是动态的(querySelectorAll()返回的NodeList除外),会根据页面元素的变化而变化。
1、NodeList和HTMLCollection相同点及不同点
相同点:
- 都是伪数组,都有length属性
- 都有item()方法(查找数组的索引)
不同点:
- NodeList可以包含12种类型的节点,HTMLCollection只包含一种节点(元素节点)
- NodeList有静态的、有动态的,HTMLCollection和NamedNodeMap都是动态集合
动态合集:DOM结构的变化能够自动的反映到保存的对象当中。
2、NodeList
NodeList 对象是节点的集合,通常是由属性,如Node.childNodes 和 方法,如document.querySelectorAll 返回的
NodeList 不是一个数组,是一个类似数组的对象(Like Array Object)。虽然 NodeList 不是一个数组,但是可以使用 forEach() 来迭代。你还可以使用 Array.from() 将其转换为数组。
不过,有些浏览器较为过时,没有实现 NodeList.forEach() 和 Array.from()。你可以用 Array.prototype.forEach() 来规避这一问题
//HTML代码
//<div id="bar">
// <p id="first">Hello World</p>
// <p class="a">增加样式 World</p>
//</div>
var aa=document.querySelectorAll('p');
console.log(aa);
//获取元素子节点的2个方法
console.log(document.body.childNodes);//换行,text也会被获取,获取的为NodeList
console.log(document.body.children);//只会获取元素节点,获取元素子节点常用此方法 获取的为HTMLCollection
console.log(document.getElementById('bar').children);
console.log(document.getElementById('bar').childNodes);
伪数组转换数组
//form()方法
console.log(Array.from(aa));
//IE中使用for循环
var selectArr=[];
for(let i=aa.length-1;i>=0;i--){
selectArr.push(aa[i])
}
NodeList详解
3、HTMLCollection
HTMLCollection 是一个接口,表示 HTML 元素的集合,它提供了可以遍历列表的方法和属性。
//HTML
//<div id="bar">
// <p id="first">Hello World</p>
// <p class="a">增加样式 World</p>
// <ul id="ul"></ul>
// <input name="myInput" type="text" size="20" /><br />
// <input name="myInput" type="text" size="20" /><br />
// <input name="myInput" type="text" size="20" /><br />
//</div>
//获取NodeList和HTMLCollection的方法,但是不同浏览器可能不太一样
console.log('querySelectorAll',document.querySelectorAll('P'));//querySelectorAll NodeList(2) [p, p.a]
console.log('getElementsByName',document.getElementsByName('myInput'));//getElementsByName NodeList(3) [input, input, input]
console.log('getElementsByTagName',document.getElementsByTagName('P'));//getElementsByTagName HTMLCollection(2) [p, p.a]
console.log('getElementsByClassName',document.getElementsByClassName('a'));//getElementsByClassName HTMLCollection [p.a]
4、关于NodeList和HTML的动态性
//HTML
//<div id="bar"></div>
var test=document.getElementById('bar');
var children=test.children;
var tag = test.getElementsByTagName('div');
console.log(children,tag);//HTMLCollection [] HTMLCollection []
//插入div,改变DOM结构
var div=document.createElement('div');
test.appendChild(div);
//合集发生了变化,这就是HTML的动态性
console.log(children,tag);//HTMLCollection [div] HTMLCollection [div]
操作属性,变量会发生对应的变化
//HTML
//<div id="bar" class="ceshi"></div>
var test=document.getElementById('bar');
console.log(test.attributes);//NamedNodeMap {0: id, 1: class, id: id, class: class, length: 2}
//增加title属性
test.setAttribute('title','测试');
console.log(test.attributes,test.attributes[2].nodeValue);//NamedNodeMap {0: id, 1: class, 2: title, id: id, class: class, title: title, length: 3} "测试"
HTML中涉及到动态性的有:HTMLCollection、NodeList、NamedNodeMap
动态合集:DOM结构的变化能够自动的反映到保存的对象当中。
5、为什么会有动态合集和静态合集
getElementById 比 querySelectorAll运行速度大概快100倍;getElementById 是直接从缓存中获取,querySelectorAll是读css选择器,然后生成快照,再把快照返回回来。
HTMLCollection详解
其他文章参考:动态合集与静态合集