2.3 Element类型
Element类型应该是Document类型之外使用的最多的节点类型了,Element代表XML或HTML文档中的一个元素,它具有以下特征:
[1]nodeType为1
[2]nodeName为标签名
[3]nodeValue为null
[4]parentNode可能是Element或Document
[5]childNode可能是Element,Text,Comment,Proccessinginstruction,CDATASection或EntityReference
除了使用nodeName,还可以使用tagName取得标签名称,但是返回的标签名都是大写的。
2.3.1 HTML元素
在HTML中,所有的HTML元素都是由HTMLElement类型或者其子类型来表示的,他们都存在以下这些标准特性:
[1]id:元素在文档中的唯一标识
[2]title:有关元素的附加说明信息,一般在鼠标移动到该元素上面时显示出来
[3]lang和dir:分别是元素内容的语言代码和语言方向,一般很少使用
[4]className:为元素设置的css类名
这些特性都是可读可写的
2.3.1 取得元素的特性
每个元素都有一个或多个特性,特性一般用来为元素提供附加信息。操作特性的DOM方法主要有三个:getAttribute()、setAttribute()和removeAttribute()。
可以通过getAttribute取得元素特性,但传入的参数必须与实际的特性名称相同,比如要获取class特性,则必须调用getAttribute("class")才可以。此外,getAttribute还可以获取自定义的特性(HTML标准语言中没有的特性),特性名称一般是不区分大小写的。
除了通过getAttribute获取元素特性,还可以通过元素的属性来获取相应的特性,除自定义特性之外(采用元素属性的方式获取自定义特性时会返回undefined,IE8及以下浏览器都会返回相应的特性值)。
有两类特殊的特性,它们虽然拥有对应的属性名,但是通过getAttribute获得的特性值却与对应的属性值不同:
首先是"style"特性,如果通过getAttribute("style"),获得的是style字符串;如果通过element.style,获得的是一个对象(IE7及以下浏览器中,使用元素属性与getAttribute方法返回的都是对象)。
另外一个特性是"onclick"这种事件处理程序特性,使用getAttribute时,返回的相应特性的字符串,而访问元素的属性返回的则是一个js函数(IE7及以下浏览器中,使用元素属性与getAttribute方法返回的都是js函数)。
2.3.2 设置元素的特性
与getAttribute相对应的是setAttribute,可以用来设置元素的特性,如果特性已经存在,则修改对应的特性;如果特性不存在,则为元素创建相应的特性,通过这个方法设置的特性名称都会转换为小写。
与getAttribute相似,也可以通过修改元素的属性来为元素设置对应的特性,但是如果是自定义特性,除IE8及以下浏览器外,都不能通过元素属性来设置。
注:在IE7及以下浏览器中,通过setAttribute设置class,style,事件处理程序没有效果。
另外还有一个方法是removeAttribute,这个方法不仅会清除对应的特性值,还会删除对应的特性,但IE6并不支持这个方法。
2.3.3 attributes属性
Element类型是唯一一个使用attributes属性的节点类型,这个属性中包含一个NamedNodeMap,与NodeList相似,也是一个动态的集合。包含以下几个方法:
[1]getNamedItem(name):根据特性名称来获取一个Attr节点
[2]removeNamedItem(name):根据名称删除一个特定的Attr节点
[3]setNamedItem(Node):向列表中添加一个Attr节点,以节点的nodeName为索引
[4]item(pos):获得对应位置索引的节点
2.3.4 创建Element节点
可以使用document.createElement方法创建一个元素,这个方法接收一个参数,即元素的标签名。创建之后的节点必须通过2.1.3节中介绍的操作节点的方法才可以将元素在页面中显示出来。
在IE中还可以传入这个元素的完整标签,比如:
document.createElement("<div id='div' name='div'>测试</div>")
这种方式有助于避开IE7及以下浏览器中动态创建元素时会出现的一些问题,目前已知的问题包括:
[1]不能设置动态创建的iframe元素的name特性
[2]不能通过reset()重置动态创建的input元素
[3]动态创建的type为reset的button不能重置表单
[4]动态创建的一批name相同的radio按钮彼此之间毫无关系
2.3.5 元素的子节点
元素可以拥有多个子节点和后代节点,因为一个元素可以是其他元素的子节点,通过childNodes属性可以获得元素的所有子节点。但是不同浏览器对于元素的childNodes属性会有不同的处理,IE8及以下浏览器不会增加空白文本节点,以下面代码为例:
<ol id="list">
<li>我是列表</li>
<li>我是列表</li>
<li>我是列表</li>
<li>我是列表</li>
</ol>
在IE8及以下浏览器中,list的childNodes的length为4,而其他浏览器中则为9,因此如果要获取元素的所有子元素节点,务必要遍历childNodes,并通过nodeType来进行筛选。
此外,Element也支持getElementsByTagName。
2.4 Text类型
Text类型代表DOM树中的文本节点,它有如下特点:
[1]nodeType为3
[2]nodeName为#text
[3]nodeValue为节点的文本字符串
[4]parentNode为Element
[5]没有childNodes
可以通过nodeValue或data属性来获取或者设置文本节点的内容,同时还有以下几个函数来操纵文本节点的文本字符串:
[1]appendData(text):将文本添加到节点末尾
[2]deleteData(offset,count):从offset处开始删除count个字符
[3]insertData(offset, text):从offset处插入text
[4]replaceData(offset, count, text):用text替换从offset之后的count个字符
[5]splitText(offset):从offset处将文本节点拆分成两个文本节点
[6]substringData(offset, count):提取offset开始的count个字符
此外,文本节点还有一个length属性,表示其内容字符串的长度,同时它的data属性和nodeValue属性也都有一个length属性。
可以通过设置文本节点的nodeValue或data属性来修改节点的内容,但是插入的内容都会经过HTML或XML编码。
2.4.1 新建文本节点
可以通过document.createTextNode()来新建一个文本节点,这个方法接收一个参数,即文本节点的内容(内容也会经过编码)。
一般情况下,一个元素只有一个文本节点,但如果向元素插入了多个文本节点,那么它也可能会包含多个文本节点。
2.4.2文本节点的规范化与分割
2.1.4节介绍过normalize方法,这个方法会处理元素包含的文本节点,比如删除空白的文本节点,合并相邻的文本节点等。另外,还可以通过文本节点的splitText方法分割文本节点,这样就会使得元素包含多个文本节点。
2.5 Comment类型
Comment类型在文档中表示注释,Comment的基本特征如下:
[1]nodeType为8
[2]nodeName为#comment
[3]nodeValue为注释的内容
[4]parentNode可能是Document或Element
[5]没有子节点
Comment类型与Text类型继承自同一个基类,因此它具有除splitText之外的所有Text类型节点所具有的方法。
可以通过document.createComment来创建一个注释节点,但是实际中我们很少会创建或者操作文本节点。
2.6 CDATASection类型
CDATASection只针对XML文档,它继承自Text,也具有除splitText之外的所有Text类型所具有的方法,它的基本特征如下:
[1]nodeType为4
[2]nodeName为#cdata-section
[3]nodeValue为CDATA区域中的内容
[4]parentNode可能是Document或Element
[5]没有子节点
Comment类型与Text类型继承自同一个基类,因此它具有除splitText之外的所有Text类型节点所具有的方法。
CDATASection只会出现在XML文档中,浏览器中一般会把其视为Comment或Element来处理。在真正的XML文档中,可以通过document.createCDataSection方法创建一个CDATASection节点
2.7 DocumentType类型
DocumentType包含着与文档类型有关的信息,它的基本特征如下:
[1]nodeType为10
[2]nodeName为doctype的名称
[3]nodeValue为null
[4]parentNode是Document
[5]没有子节点
在DOM1中,DocumentType类型不能动态创建,而只能通过解析页面代码的方式创建,支持它的浏览器会DocumentType对象保存在document.doctype中,DOM1中描述了doctype的三个属性:
[1]name:表示文档类型的名称
[2]entities:是文档类型描述的实体的NamedNodeMap对象
[3]notations:是文档类型描述的符号的NamedNodeMap对象
通常情况下,只有name属性是有用的
2.8 DocumentFragment类型
在所有的节点类型中,只有DocumentFragment在文档中没有对应的标记,它是一种轻量级的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源,它的基本特征如下:
[1]nodeType为11
[2]nodeName为#document-fragment
[3]nodeValue为null
[4]parentNode为null
[5]childNode可能是Element,Text,Comment,Proccessinginstruction,CDATASection或EntityReference
DocumentFragment类型继承了Node的所有方法,主要用于执行针对文档的DOM操作,可以使用document.createDocumentFragment方法创建一个文档片段,它的使用有如下特点:
(1)如果把文档树中的节点添加到文档片段中,那么就会从文档树中移除该节点;而添加到文档片段中的节点也不会在文档树中显示
(2)可以通过appendChild、insertBefore或replaceChild方法将文档片段添加到文档树中,而这个操作只是把文档片段的所有子节点添加到了文档树中,文档片段本身是不会被添加到文档树中的。
2.9 Attr类型
特性节点是用来表示元素特性的,它也是存在于attributes属性中的节点,它的基本特征如下:
[1]nodeType为2
[2]nodeName为特性名称
[3]nodeValue为特性的值
[4]parentNode为null
[5]没有子节点
Attr对象有三个属性:name,value和specified,name与nodeName属性对应,value与nodeValue属性对应,而specified则表示特性是否是在代码中指定的。
可以通过document.createAttribute方法创建一个特性节点,并且通过Element的setAttributeNode方法为元素添加特性。
注:实际中一般很少直接操作特性节点,而是通过getAttribute、setAttribute和removeAttribute方法,或者通过元素对象属性的方式来操作元素的特性
在平时的DOM编程中,使用最多的应该是Document、Element和Text类型,DOM1中为这些节点的操作提供了底层的支撑和基础的方法,后面的文章会陆续介绍后续对DOM1级的扩展,以及DOM2和DOM3所带来的新的变化。