最近在看《Javascript高级程序设计》的时候,看到了这样一句话:“理解NodeList和HTMLCollection,是从整体上透彻理解DOM的关键所在。”,所以觉得应该写一篇关于NodeList和HTMLCollection的博客来好好了解和总结下这方面的知识点。

NodeList

  NodeList是一个节点的集合(既可以包含元素和其他节点),在DOM中,节点的类型总共有12种,通过判断节点的nodeType来判断节点的类型。

  我们可以通过Node.childNodes和document.querySelectAll() (返回NodeList的接口有很多,这里不一一列举,下同)来获取到一个NodeList对象。

  NodeList对象有个length属性和item()方法,length表示所获得的NodeList对象的节点个数,这里还是要强调的是节点,而item()可以传入一个索引来访问Nodelist中相应索引的元素。

 <body>
<div id="node">
文本节点
<!-- 注释节点 -->
<span>node1</span>
<span>node2</span>
<span>node3</span>
</div>
</body>
<script>
var node = document.getElementById('node'),
nodeLists = node.childNodes
console.log(nodeLists.length) // 输出为9
</script>

  上面的HTML代码中,“文本节点”和父节点子节点的空格(连着的文本)算做一个文本节点,然后是一个注释节点和注释节点和元素节点之间的空格(换行会产生空格,空格算做文本节点)的文本节点,紧接着的是一个元素节点和元素节点之间的换行的文本节点,三个元素节点和元素节点间的两个文本节点,最后是最后得元素节点和父元素之间的空格产生的文本节点,总共是9个节点。

  NodeList对象的一大特点是它返回的内容是动态的(live),也就是说我们上面代码获取nodeLists是类似于“指针”的东西,所以在下面代码中我们在获取了nodeLists之后再向node中插入一个创建的span标签后,发现获取到了nodeLists.length变为10了,但是querySelectorAll这个接口返回的nodeList对象比较特殊,它是个静态(static)的对象。而且是元素的集合。

 <body>
<div id="node">
文本节点
<!-- 注释节点 -->
<span>node1</span>
<span>node2</span>
<span>node3</span>
</div>
</body>
<script>
var node = document.getElementById('node')
var nodeLists = node.childNodes
var queryNodes = node.querySelectorAll('span')
node.appendChild(document.createElement('span'))
console.log(nodeLists.length) // 输出为10
console.log(queryNodes.length) //输出为3
</script>

  HTMLCollection

  HTMLCollection是元素集合,它和NodeList很像,有length属性来表示HTMLCollection对象的长度,也可以通过elements.item()传入元素索引来访问。当时它还有一个nameItem()方法,可以返回集合中name属性和id属性值得元素。HTMLDocument 接口的许多属性都是 HTMLCollection 对象,它提供了访问诸如表单、图像和链接等文档元素的便捷方式,比如document.images和document.forms的属性都是HTMLCollection对象。

 <body>
<img src="test.png" id="image1">
<img src="test.png" id="image2">
<img src="test.png" id="image3">
<img src="test.png" id="image4">
<img src="test.png" id="image5">
<img src="test.png" id="image6">
</body>
<script>
console.log(document.images.namedItem('image1')) //<img src="test.png" id="image1">
</script>

  HTMLCollection的集合和NodeList对象一样也是动态的,他们获取的都是节点或元素集合的一个引用。

  HTMLCollection和NodeList 实时性

  前面都说到了它们连个对象都不是历史文档状态的一个静态快照,而是实时性的,这个是一个非常令人惊讶的特性,它们能随着文档的改变而改变,这个是很值得我们注意的,我们在平常使用一些DOM 接口来返回一些DOM集合的时候,常常会忽视掉这些。

  HTMLCollection和NodeList的实时性非常有用,但是,我们有时要迭代一个NodeList或HTMLCollection对象的时候,我们通常会选择生成当前对象的一个快照或静态副本:

  

 var staticLists = Array.prototype.slice.call(nodeListorHtmlCollection, 0)

 这样的话,我们就可以放心的对当前的DOM集合做一些删减和插入操作,这个在DOM密集操作的时候很有用。

  还有MDN上面提到了一个将NodeList转化为Array的DOM扩展原型的方法(在IE6/7中存在危险:http://perfectionkills.com/whats-wrong-with-extending-the-dom/):

var arrayMethods = Object.getOwnPropertyNames( Array.prototype );
arrayMethods.forEach( attachArrayMethodsToNodeList );
function attachArrayMethodsToNodeList(methodName)
{
if(methodName !== "length") {
NodeList.prototype[methodName] = Array.prototype[methodName];
}
};
var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];
firstDiv.childNodes.forEach(function( divChild ){
divChild.parentNode.style.color = '#0F0';
});

  结语

  DOM最初设计是为了解析XML而设计的,之后沿用到HTML上。我们可以把DOM分为两部分 core 和 html,Core 部分提供最基础的 XML 解析API说明,HTML 部分专为 HTML 中的 DOM 解析添加其特有的 API。NodeList接口是在core中体现的,HTMLCollection则是在html部分,不同浏览器也会实现它们的不同接口,厂商联盟性质的规范组织出现会让这些更加规范,也不出现之前返回的是NodeList对象,但是却是静态的。

  这篇文章很多思想都是自己在平时和网上了一些博客中了解到了,其中加了很多自己的组织和理解,目的在于梳理下一些比较深入的知识点,如果写的有疏漏和错误之处,还请指出。

 

  

DOM中的NodeList与HTMLCollection的更多相关文章

  1. DOM中的动态NodeList与静态NodeList

    GitHub版本号: https://github.com/cncounter/translation/blob/master/tiemao_2014/NodeList/NodeList.md 副标题 ...

  2. 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap

    × 目录 [1]NodeList [2]HTMLCollection [3]NamedNodeMap[4]注意事项 前面的话 一说起动态集合,多数人可能都有所了解.但是,如果再深入些,有哪些动态集合, ...

  3. 在DOM中搜索元素

    方法 现代浏览器中使用XPath document.getElementById document/node.getElementsByTagName Limit search by parent e ...

  4. javascript高级程序设计---NodeList和HTMLCollection

    节点对象都是单个节点,但是有时会需要一种数据结构,能够容纳多个节点.DOM提供两种接口,用于部署这种节点的集合分别是NodeList和HTMLCollection MDN上的定义: NodeList: ...

  5. 浅谈JavaScript和DOM中的类数组对象

    JavaScript是一门弱类型语言,它的数据类型分为两大类:简单数据类型(5种:Undefined.Null.Boolean.Number.String)和复杂数据类型(1种:Object).Obj ...

  6. NodeList、HTMLCollection和NamedNodeMap

    上篇文章以arguments为例讲到了类数组对象,这篇我们讨论更多的类数组对象NodeList.HTMLCollection和NamedNodeMap.既然是类数组对象,这3种对象也都能应用上篇文章中 ...

  7. html5中的dom中的各种节点的层次关系是怎样的

    html5中的dom中的各种节点的层次关系是怎样的 一.总结 一句话总结:Node节点是所有节点的基类,所以都继承它的方法 1.dom提供在js中动态修改html标签的作用 比如增加修改标签等,并且是 ...

  8. javascript DOM中的节点层次和节点类型概述

    针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内.写这个主要是当个笔记加总结 存在的问题请大家多多指正! 因为DOM这方面的对象方法操作性都特别强,但是逻辑很简单,所以就没有涉及到实际的 ...

  9. Dom中的一些接口

    节点都是单个对象,有时需要一种数据结构,能够容纳多个节点.DOM 提供两种节点集合,用于容纳多个节点:NodeList和HTMLCollection.这两种集合都属于接口规范.许多 DOM 属性和方法 ...

随机推荐

  1. HTML入门学习

    html 基本结构    <!DOCTYPE html> ----------------声明文档的解析类型, 避免浏览器的怪异模式<html> --------------- ...

  2. JS+CSS+HTML简单计算器

    <!doctype html> <html> <head> <title>计算器</title> <meta charset=&quo ...

  3. Supervisor的一些基础使用

    Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...

  4. php代码的一些高效写法

    用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说 ...

  5. 如何使用sublime编辑器运行python程序

    现在越发喜欢sublime编辑器了,不仅界面友好美观.文艺,可扩展性还特别强. sublime本身是不具备运行python程序的能力的,需要做些设置才可以.以下是安装好sublime后设置的步骤: 点 ...

  6. swift代码排版-参考

    代码排版包括: 空行.空格.断行和缩进等内容.代码排版内容比较多工作量很多,但是非常重要. 空行 空行将逻辑相关的代码段分隔开,以提高可读性.下列情况应该总是添加空行: 类型声明之前. import语 ...

  7. github使用入门 之GIT GUI Windows版

    申明下是原创. 这二天网上也看了不少关于github使用的文章,github对代码管理也开始用起来了.这篇给github新手看,大牛们请跳过. github说白了就是版本管理库,最常用的就是程序代码管 ...

  8. C# and android and socket

    利用TCP协议通过Socket编写的网络聊天工具1-客户端 利用TCP协议通过Socket编写的网络聊天工具2-通用类设计 利用TCP协议通过Socket编写的网络聊天工具3-服务器端设计

  9. Android中的一些小知识

    android中开发常用快捷键alt+/ 自动补全ctrl+1 有问题提示生成接收的参数 ctrl+L 在按2 注释// 注释 ctrl+//**/ 多行注释 ctrl+shift+/ android ...

  10. java中Runnable接口含义

    Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口. Runnable接口非常简单,就定义了一个方法run(),继承Runnable并实现这个 方法就可以实现多线程了,但是 ...