NodeList、HTMLCollection和 NamedNodeMap

NodeList、HTMLCollection和 NamedNodeMap都是通过某些方法获得的节点的集合(类数组的形式),它们的区别主要在保存节点的类型,访问节点的方式上。我们来一一介绍:

1. NodeList

1.1 包含节点类型

既可以包含元素节点,也可以包含其他类型的节点,如文本节点、注释节点等。

1.2 获取方式

node.childNodes;
node.querySelectorAll();

另外,在除了 IE 的其它浏览器中,document.getElementsByName() 返回的集合也是 NodeList 类型的集合

注:node 可以是 document 或 element 节点

1.3 使用方法

  • 类数组。之所以叫类数组是因为像数组那样,它的元素有序排列,并可以通过数字索引被访问,而且它还有length 属性,保存其元素的数目;但是,它并没有真正的数组所拥有的那些方法,比如 forEach(),filter()。
  • 只读性。无法通过单纯操作数组来增删其中的元素。
  • 动态性(通过 childNodes 属性和 getElementsByName() 方法获取的该类型的集合有这个特点)。实时同步 DOM 树的变化,若 DOM 树中有新元素加入,那么数组中就会将新元素添加进来。当执行流再一次碰到该数组时,数组中一定包含了新添加的数组。
  • 静态性(通过 querySelectorAll() 方法获取的该类型的集合有这个特点)。理解了动态性,静态性就好理解了。无论 DOM 以后怎么增删节点,都与现在获取的集合无关了。

2. HTMLCollection

2.1 包含节点的类型

只能包含元素节点

2.2 获取方式

node.getElementsByTagName();
node.getElementsByClassName();

document.anchors;
document.links;
document.forms;
document.images;

另外,在 IE 中,document.getElementsByName() 返回的也是 HTMLCollection 类型的集合

注:node 可以是 document 或 element 节点

2.3 使用方法

  • 类数组
  • 只读性
  • 动态性

前三条和 NodeList 中的特点是一样的,不过,HTMLCollection 比 NodeList 多了一条是:

  • 可以通过元素的 id 和 name 特性的名称来获取元素;

3. NamedNodeMap

3.1 包含节点的类型

元素节点下的特性节点

3.2 获取方式

element.attributes;

3.3 使用方法

  • 只读性
  • 动态性

上面这两条跟前面的定义是一样的,不一样的是下面这一条:

  • 特别版类数组。之所以称它为特别版,是因为它是无序集合,虽然可以通过数字索引来获取节点,但是该索引并不真实代表特性在元素中的位置。

这个集合的实用性不是很强,一般对特性的操作都可以通过 getAttribute()、setAttribute() 和 removeAttribute()来完成。

4. 将类数组转化为数组

HTMLCollection 和 NodeList 的动态性非常有用,但是,我们有时候需要迭代一个 HTMLCollection 或者 NodeList 集合,这就需要我们生成一个集合的副本,我们可以将它转化为数组类型:

var staticList = Array.prototype.slice.call(nodelist/htmlcollection, 0);

这种方法得到的数组跟 querySelectorAll 方法得到的类数组一样是静态的,在迭代集合的时候可以用这两种方法。
本文参考:

  1. NODELIST V.S. HTMLCOLLECTION
  2. JS魔法堂:那些困扰你的DOM集合类型