DOM中的NodeList与HTMLCollection

  最近在看《Javascript高级程序设计》的时候,看到了这样一句话:“理解NodeList和HTMLCollection,是从整体上透彻理解DOM的关键所在。”,所以觉得应该写一篇关于NodeList和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 实时性

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

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

  

1 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对象,但是却是静态的。

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

  

时间: 2024-10-25 20:19:26

DOM中的NodeList与HTMLCollection的相关文章

DOM中的动态NodeList与静态NodeList

GitHub版本: https://github.com/cncounter/translation/blob/master/tiemao_2014/NodeList/NodeList.md 副标题: 为何getElementsByTagName()比querySelectorAll()快100倍 昨天,我在雅虎的同事 Scott Schiller (斯科特·席勒, 同时也是SoundManager创造者) 发Twitter询问为何getElementsByTagName("a") 在

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

× 目录 [1]NodeList [2]HTMLCollection [3]NamedNodeMap[4]注意事项 前面的话 一说起动态集合,多数人可能都有所了解.但是,如果再深入些,有哪些动态集合,以及这些动态集合有什么表现.区别和联系?可能好多人就要摇头了.本文就javascript中的动态集合做详细介绍 NodeList NodeList实例对象是一个类数组对象,它的成员是节点对象,包括childNodes和querySelectorAll()方法返回值 <div id="test&

在DOM中搜索元素

方法 现代浏览器中使用XPath document.getElementById document/node.getElementsByTagName Limit search by parent element document.getElementsByName document/node.getElementsByClassName document/node.querySelector, querySelectorAll 实践 标签链接 显示子节点数量 更多 总结 大部分时间里,为了与用

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

节点对象都是单个节点,但是有时会需要一种数据结构,能够容纳多个节点.DOM提供两种接口,用于部署这种节点的集合分别是NodeList和HTMLCollection MDN上的定义: NodeList: NodeList对象是通过Node.childNodes和document.querySelectorAll方法返回的(collections of nodes)节点的集合, NodeList一般是动态集合live collection, 是即时更新的(live):当其所包含的文档结构发生改变时,

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

针对JS高级程序设计这本书,主要是理解概念,大部分内容源自书内.写这个主要是当个书中的笔记加总结 存在的问题请大家多多指正! 因为DOM这方面的对象方法操作性都特别强,但是逻辑很简单,所以就没有涉及到实际的代码. 另外这篇不包括DOM2,DOM3的内容 DOM 文档对象模型,针对HTML和XML文档的一个API.描绘了一个层次化的结点树,循序开发人员添加,移除修改页面上的一部分. 1节点层次 DOM把文档描绘成一个由多层节点构成的结构.节点有不同的类型.节点之间的关系构成了层次. 文档节点是每个

js—— DOM中的node类型(二)

DOM中的node类型 DOM1中定义了一个Node接口,这个接口在js中作为Node类型实现,除IE外,其他浏览器都可以访问到这个类型.Js中所以节点类型都继承自Node类型,节点类型都享有共同的·基本属性和方法. 每个节点都有nodeType属性,表明节点类型,由12个常量表示,任何节点必居其一. Node.ELEMENT_NODE 1 元素节点 Node.ATTRIBUTE_NODE 2 属性节点 Node.TEXT_NODE 3 文本节点 ...... 常用的为以上三种,还有其他类型可去

JQ中的clone()方法与DOM中的cloneNode()方法

JQ中的clone()方法与DOM中的cloneNode()方法 cloneNode()定义和用法 cloneNode()方法创建节点的拷贝,并返回该副本. 语法: node.cloneNode(deep);  其接收一个可选参数"deep",为布尔类型,默认是false. 当设置为true,克隆当前节点,属性及当前节点的后代.若设置为false,仅仅克隆当前元素节点本身. 扩展:  使用cloneNode()方法,当被克隆的节点绑定了事件处理程序,事件处理程序是否会被一同克隆,这个我

HTML中常见的各种位置距离(clientTop clientLeft clientWidth ClientHeight offsetleft offsettop offsetwidth offsetheight等等)以及dom中的坐标讨论

最近在学习JavaScript,特意买了一本犀牛角书来看看,尼玛一千多页,看的我头昏脑涨,翻到DOM这章节,突然记起平常在使用DOM时,碰到了好多的这个dom里面的各种宽度,高度,特意在此写一写,写的不好或者写错了,欢迎各位指正.好了废话不多说,开始进入主题. 这篇文章主要讨论两点: 一.DOM中各种宽度.高度 二.DOM中的坐标系 下面我们看看DOM中都有一些什么宽度.高度. 常见的 offsetWidth clientWidth scrollWidth offsetHeight client

javascript判断元素存在和判断元素存在于实时的dom中的方法

今天(周六)下午我在公司加班时不知道要干什么,就打开公司的一个wordpress项目网站,想看下之前自己做的一个网页是否有问题. 打开网站首页,我习惯性的打开了chrome的调试工具,然后鼠标开始滚动页面,然后问题就出来了:页面无法向下滚动,调试工具的console里报了好多undefined的错误. 我马上意识到是我写的js代码错误的在首页被执行导致的问题,我的代码大致是这样: 1 if ($('#a')) { 2 // some code ... 3 $('#b').doSomething;