在前台开发中,我们做的最多的操作之一便是遍历给定DOM节点的节点,并对相应的子节点做一些进一步的操作,如:节点排序,添加样式,ect。在本地的DOM元素节点上存在这样两个属性children和childNodes,通过这两个属性我们都能完成一般性的子节点操作,由于这两个属性在名称上十分相似,我们通常困惑于到底该使用哪个属性,本文现就这两个属性的特点和相互之间的区别做简单的介绍。
Element.children
作用:返回给定元素节点的元素节点集合。
1.非W3C标准 , 但是基本上所有的浏览器都实现了该属性,所以也可以称作是事实上的标准
2.基本语法 var elCol = elemNode.children ;
3..返回值类型:HTMLCollection , 包含当前元素的所有子元素节点(Element Node)的有序列表集合。如果没有子元素节点那么该集合的长度为0;
4.兼容性列表
Feature |
Chrome |
Firefox (Gecko) |
Internet Explorer |
Opera |
Safari |
Basic support |
1 |
3.5 |
9 (IE6-8 incl commend nodes) |
10 |
4 |
注意的IE9之前的版本(IE6/7/8)会列出注释节点
5.例子:
//将ul(#list)下所有节点索引为基数的li元素的背景变为黄色
<ul id="list"> <!--This is a comment node--> <li>item-1</li> <li>item-2</li> <li>item-3</li> </ul>
//在parentElem的所有子元素节点上调用fn函数
function elemEach(parentElem , fn){ if(parentElem && parentElem .nodeType==1 && parentElem.children && typeof fn =="function"){ var elCol = parentElem .children; var length = elCol.length ; var curElemNode = null ; for(var i = 0 ; i < length ; i++){ curElemNode = elCol.item(i) //过滤掉IE中的comment类型节点 if(curElemNode.nodeType == 1){ fn(i ,curElemNode) ; } } } } var list = document.getElementById("list"); elemEach(list , function(index , elem){ if((index+1) % 2 == 0){ elem.style.backgroundColor = "yellow" ; } });
6.该属性为只读属性,同样不能通过为该属性赋值来改变父节点的子节点内容,如
//此操作不起任何作用
list.children = document.createElement("div");
Element.childNodes
作用:返回给定元素节点的所有子节点集合
1.W3C标准 ,参见http://www.w3.org/TR/2012/WD-dom-20120405/#interface-node
2.基本语法 val childNodeList = elemNode.childNodes ;
3.返回值类型:NodeList , 包含当前元素的所有子节点的有序列表,子节点类型包括:元素节点(Element Node),注释节点(Comment Node),文本节点(Text Node),没有子节点时,该集合的长度为0;
4.兼容性 IE/Chrome/Firefox/Safari/Opera
5.例子:
//将ul(#list)下所有节点索引为基数的li元素的背景变为黄色
<ul id="list"> <!--This is a comment node--> <li>item-1</li> <li>item-2</li> <li>item-3</li> </ul>
//在parentElem的所有子元素节点上调用fn函数
function elemEach(parentElem , fn){ if(parentElem && parentElem .nodeType==1 && typeof fn =="function"){ var elCol = parentElem .childNodes; var length = elCol.length ; var curElemNode = null ; var elemIndex = 0 ; for(var i = 0 ; i < length ; i++){ curElemNode = elCol.item(i) //过滤掉 CommentNode , TextNode if(curElemNode.nodeType == 1){ fn(elemIndex ,curElemNode) ; elemIndex++; } } } } var list = document.getElementById("list"); elemEach(list , function(index , elem){ if((index+1) % 2 == 0){ elem.style.backgroundColor = "yellow" ; } });
6.该属性为只读属性,不能通过为该属性赋值来改变父节点的子节点内容,如
//此操作不起任何作用
list.childNodes = document.createElement("div");
小结:
从以上对两个属性的简单介绍中我们可以大致看出它们的一些共性和区别,如下
共性:
1.基本语法结构相同
2.都为只读属性
3.主流浏览器都实现了两个属性
区别:
1.标准的差异性
children非W3C标准 ; childNodes为W3C DOM标准
2.返回值类型的差异性
children返回值类型为HTMLCollection
参见:http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html 中关于Interface HTMLCollection的定义
childNodes返回值类型为NodeList
参见:http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 中关于Interface NodeList接口的定义
3.返回结合中元素类别的差异性
children返回集合中只包含元素节点类型的子节点(IE6/7/8有些特殊,包含了注释节点)
childNodes返回集合中包含了元素节点,注释节点,文本节点类型的子节点
注意:
W3C正在起草中的DOM4标准中,在Node接口的定义中已经加入了children属性,即在不久的将来children属性也将成为W3C的DOM标准
参考:
1>MDN
https://developer.mozilla.org/En/DOM/Node.childNodes
https://developer.mozilla.org/en/DOM/Element.children
2>W3C
http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html
http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177
http://dom.spec.whatwg.org/#interface-node