NodeList v.s. HTMLCollection
重要有两个方面不一样
1.包括节点的范例
2.运用要领
1.包括节点的范例差别(重要)
(1)NodeList
一个节点的鸠合,既能够包括元素和其他节点(解释节点、文本节点等)。
(2)HTMLCollection
元素鸠合, 只需Element
2.运用要领
雷同点:
1) 它们都有length属性
2) 都有元素的getter,叫做item,能够传入索引值取得元素。
3) 都是类数组
差别点:
HTMLCollection另有一个nameItem()要领,能够返回鸠合中name属性和id属性值的元素。(部份浏览器也支撑NodeList的nameItem()要领)
细致解说
触及猎取元素的重要API
DOM最初设想是为了剖析XML而设想的,以后沿用到HTML上。我们能够把DOM分为两部份 core 和 html,Core 部份供应最基本的 XML 剖析API申明,HTML 部份专为 HTML 中的 DOM 剖析增加其特有的 API。NodeList接口是在core中表现的,HTMLCollection则是在html部份,差别浏览器也会完成它们的差别接口。然则如今的dom规范已不分core和html了,反应的是浏览器的完成()。唯一要注重的是 querySelectorAll 返回的虽然是 NodeList ,然则实际上是元素鸠合,并且是静态的(其他接口返回的HTMLCollection和NodeList都是live的)。
DOM中的NodeList NamedNodeMap 及 HTMLCollection
把这三个放在一同说,是因为三者都是DOM中的array-like对象,即类数组对象(因而也都具有length属性)。
(1)先说NamedNodeMap这个对象,这个比较简朴,虽然翻译过来是 定名的节点映照,但它只不过是 Attr这个对象的一个鸠合,Attr对象是DOM元素节点的属性的对象表达。经由过程元素节点(element node)的attributes属性返回的就是NamedNodeMap这个对象。与NodeList雷同的是它也是一个动态的鸠合(live collection),与NodeList差别的是,NamedNodeMap中保留的是一组无序的属性节点的鸠合。
(2)NodeList对象是由childNodes属性,querySelectorAll要领返回的一组节点的鸠合,它保留着一组有序的节点。注重区分的是,由childNodes属性返回的NodeList对象是一个动态的鸠合(live collection), 而由querySelectorAll要领返回的则是一个静态的鸠合(static collection)。因而在MDN中将他定义为 ”A sometimes-live collection“,live collection 指的是对对DOM的操纵引发的的变化会及时的反应在这个鸠合里。
(3)接下来就是HTMLCollection,它在实质是一个动态的NodeList对象。getElementsByTagName等要领返回的是包括零或多个元素的NodeList,在HTML文档中,返回的则是HTMLCollection对象。因而说它在实质上一个NodeList对象,包括一组有序(in document order基于文档构造递次)的动态鸠合。
在猎取原生DOM元素的时刻,重要触及这几个DOM API(链接为Living Standard):
• Node及对应鸠合NodeList
• Element(继续Node)及对应鸠合HTMLCollection
• Document(继续Node)
注:设计庖代NodeList和HTMLCollection的Elements现在并没有普遍完成
基本知识 — NodeList v.s. HTMLCollection
运用Node Interface的要领,如childNodes,取得的通常是NodeList,而运用其他Interface的要领,又有能够取得HTMLCollection。所以有必要相识一下这两者的区分。
关于这两个范例的差别,在Stackoverflow上有一个不错的问答。
实在,只需先看看Living Standard中这两个范例的IDL,便能猜出也许了。NodeList的IDL以下:
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node>;
};
而HTMLCollection的IDL以下:
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
雷同点:
4) 都是类数组对象
5) 它们都有length属性
6)都有元素的getter,叫做item
差别点:
1.NodeList的元素是Node,HTMLCollection的元素是Element。
Element继续自Node,是Node的一种,在HTML中,它平常是HTML元素(比方<p>之类的标签建立出来的对象)。而Node作为父类,除了Element另有一些其他子类,比方HTML元素内的文本对应的Text,文档对应的Document,解释对应的Comment。HTMLCollection里,只需Element,而NodeList里能够有Element、Text、Comment等多种元素。按说假如猎取元素返回的列内外只需Element,那这两种类没多大区分,但事实上很多时刻浏览器会将剖析HTML文本时取得的Text和Comment一并放进列内外放回。比方说下面这一段代码
<div>
<!-- Comment -->
<p>This is Some Text</p>
</div>
若将这个div的子元素放在列内外返回,那末假如是作为NodeList返回,浏览器最多能够给这个列表5个元素(差别浏览器能够差别)
1. 一个<div>和解释间的断行和空格(或tab)作为text node(没错,标签之间的空缺标记也能够被剖析为text node)
2. 解释作为comment node
3. 解释和<p>之间的断行和空格(或tab)作为text node
4. p作为element
5. </p>和</div>之间的断行和空格(或tab)作为text node
因而NodeList里能够会有很多平常DOM操纵不须要的text node和comment node须要处置惩罚。而HTMLCollection则简朴多了,只需<p>这一个元素,这也是比较相符大多数人直觉的效果。
2.HTMLCollection另有一个namedItem要领,能够疾速猎取个中元素。假定有如许一段HTML:
<div>
<!-- Comment -->
<p>This is Some Text</p>
<img name="test" src="test.jpg">
</div>
那末假定取得了这个div的子元素组成的HTMLCollection,叫做list,那末运用list.namedItem(“test”)就能够直接取得内里的img元素。
查找递次参考Living Standard,然则在实际中不是一切浏览器都遵照规范。比方规范划定假如有多个具有雷同id或许name的元素,只需返回第一个,但chrome和opera会将它们放在一个HTMLCollection或许NodeList里一并返回,拜见MDN。
从IDL看不出来的另有以下几点
1. 这两个类都是“live”的。对个中元素举行操纵,会及时反应到DOM中(也因而假如一次性直接在这类列表上举行多个DOM操纵的话,带来的开支会很大)。
2. item和namedItem都能够经由过程[]的缩写举行挪用,有的浏览器还支撑用()的缩写举行挪用(也就是能够list[index],list[key]或许list(index),list(key)),以及直接用dot notation挪用namedItem(比方list.key)。
3. 部份浏览器支撑对NodeList挪用namedItem或间接经由过程[]、()、dot notation来挪用namedItem,但由于各浏览器支撑差别,最好不对NodeList做这类操纵。
4. IE8及以下版本浏览器中,解释属于HTMLCommentElement,算作Element,因而会出如今HTMLCollection里。
NodeList
NodeList是一个节点的鸠合(既能够包括元素和其他节点),在DOM中,节点的范例总共有12种,经由过程推断节点的nodeType来推断节点的范例。
我们能够经由过程Node.childNodes和document.querySelectAll() (返回NodeList的接口有很多,这里不一一列举,下同)来猎取到一个NodeList对象。
NodeList对象有个length属性和item()要领,length示意所取得的NodeList对象的节点个数,这里照样要强调的是节点,而item()能够传入一个索引来接见Nodelist中响应索引的元素。
1 <body>
2 <div id="node">
3 文本节点
4 <!-- 解释节点 -->
5 <span>node1</span>
6 <span>node2</span>
7 <span>node3</span>
8 </div>
9 </body>
10 <script>
11 var node = document.getElementById('node'),
12 nodeLists = node.childNodes
13 console.log(nodeLists.length) // 输出为9
14 </script>
上面的HTML代码中,“文本节点”和父节点子节点的空格(连着的文本)算做一个文本节点,然后是一个解释节点和解释节点和元素节点之间的空格(换行会发生空格,空格算做文本节点)的文本节点,紧接着的是一个元素节点和元素节点之间的换行的文本节点,三个元素节点和元素节点间的两个文本节点,末了是末了得元素节点和父元素之间的空格发生的文本节点,总共是9个节点。
NodeList对象的一大特点是它返回的内容是动态的(live),也就是说我们上面代码猎取nodeLists是类似于“指针”的东西,所以在下面代码中我们在猎取了nodeLists以后再向node中插进去一个建立的span标签后,发明猎取到了nodeLists.length变成10了,然则querySelectorAll这个接口返回的nodeList对象比较特别,它是个静态(static)的对象。而且是元素的鸠合。
1 <body>
2 <div id="node">
3 文本节点
4 <!-- 解释节点 -->
5 <span>node1</span>
6 <span>node2</span>
7 <span>node3</span>
8 </div>
9 </body>
10 <script>
11 var node = document.getElementById('node')
12 var nodeLists = node.childNodes
13 var queryNodes = node.querySelectorAll('span')
14 node.appendChild(document.createElement('span'))
15 console.log(nodeLists.length) // 输出为10
16 console.log(queryNodes.length) //输出为3
17 </script>
HTMLCollection
HTMLCollection是元素鸠合,它和NodeList很像,有length属性来示意HTMLCollection对象的长度,也能够经由过程elements.item()传入元素索引来接见。当时它另有一个nameItem()要领,能够返回鸠合中name属性和id属性值得元素。HTMLDocument 接口的很多属性都是 HTMLCollection 对象,它供应了接见诸如表单、图象和链接等文档元素的便利体式格局,比方document.images和document.forms的属性都是HTMLCollection对象。
1 <body>
2 <img src="test.png" id="image1">
3 <img src="test.png" id="image2">
4 <img src="test.png" id="image3">
5 <img src="test.png" id="image4">
6 <img src="test.png" id="image5">
7 <img src="test.png" id="image6">
8 </body>
9 <script>
10 console.log(document.images.namedItem('image1')) //<img src="test.png" id="image1">
11 </script>
HTMLCollection的鸠合和NodeList对象一样也是动态的,他们猎取的都是节点或元素鸠合的一个援用。
HTMLCollection和NodeList的及时性异常有效,然则,我们偶然要迭代一个NodeList或HTMLCollection对象的时刻,我们通常会挑选天生当前对象的一个快照或静态副本:
转换为数组范例:
var staticLists = Array.prototype.slice.call(nodeListorHtmlCollection, 0)
如许的话,我们就能够宁神的对当前的DOM鸠合做一些删减和插进去操纵,这个在DOM麋集操纵的时刻很有效。