从children与childNodes说说nodeType

image

nodeType

在读Zepto v1.2.0的源码时,有处函数如下,用来获取子元素

1
2
3
4
5
function children(element) {
return 'children' in element ?
slice.call(element.children) :
$.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
}

里面涉及到了childrenchildNodes两个属性,函数中首先判断children属性是否存在,否则从childNodes属性中获取所需元素。
对于这些属性首先看下在MDN中的解释:

ParentNode.children 是一个只读属性,返回 一个Node的子elements 的HTMLCollection

HTMLCollection 接口表示一个包含了元素(元素顺序为文档流中的顺序)的通用集合(generic collection)。

ChildNodes 接口包含特定于Node 对象的方法,这些对象可以有一个父对象。

节点有多种类型,比如元素、文本和注释,区分这些节点可以通过检查nodeType 属性。共计有12种节点类型,其中比较有代表性的如下:

节点类型 描述 常量
Element 一个元素节点, 如<p><div> 1 ELEMENT_NODE
Attr 属性 2 ATTRIBUTE_NODE
Text Element或者Attr中实际的文字 3 TEXT_NODE
Comment 注释 8 COMMENT_NODE
Document 代表整个文档(DOM 树的根节点) 9 DOCUMENT_NODE

HTML DOM nodeType 属性

也就是说,childNodes包含了children的内容。
回到zepto中,children函数获取了父元素中所有子元素,并以数组的形式返回;而childNodes则筛选了nodeType == 1的节点,即 Element类型的节点。

除此之外,zepto在其他地方同样用到了nodeType相关的属性,在上面的表格中有判断节点类型的常量来代替数字值。所以zepto在判断是否为document函数中写成了如下形式:

1
function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }

其中DOCUMENT_NODE的值为9

此children非彼children

zepto源码中继续查找可以发现$.fn上同样定义了一个children函数,这里的函数实际上就是平常所使用的选择器了,能够把获取到的数组转换为zepto类型。

1
2
3
4
5
$.fn = {
children: function(selector){
return filtered(this.map(function(){ return children(this) }), selector)
}
}

nodeType