6.1 什么是DOM?
6.1.1 XML简介
XML(可扩展标记语言)是从SGML(标准通用标记语言)派生出来的。它采用了如下语法:
l 任何起始标签都必须有一个结束标签
l 可以采用一种简化语法,在一个标签中同时表示起始和结束标签,如<tag/>
l 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签
l 所有的属性都必须有值
l 所有的属性都必须在值得周围加上双引号
6.1.2 针对XML的API
SAX(Simple API for XML)提供了一个基于事件的XML解析的API。它从文件的开头出发,从前向后解析,每当遇到起始标签或者结束标签、特性、文本或者其他的XML语法时,就会触发一个事件。
DOM是针对XML的基于树的API。它不仅仅是解析XML代码,而是使用一系列互相关联的对象来表示这些代码,而这些对象可以被修改且不需重新解析代码就能直接访问它们。
使用DOM,只需解析代码一次来创建一个树模型,在这个解析过程之后,XML已经完全通过DOM模型来表现出来,同时不再需要原始的代码。
6.1.3 节点的层次
当谈论DOM树的时候,实际上谈论的是节点(node)的层次。DOM定义了Node的接口以及许多种节点类型来表示XML节点的多个方面:
l Document——最顶层的节点,所有的其他节点都是附属于它的。
l DocumentType——DTD引用(使用<!DOCTYPE>语法)的对象表现形式。它不能包含子节点。
l DocumentFragment——可以向document一样来保存其他节点。
l Element——表示起始标签和结束标签之间的内容。这是唯一可以同时包含特性和子节点的节点类型。
l Attr——代表一对特性名和特性值。这个节点不能包含子节点。
l Text——代表XML文档中的在起始标签和结束标签之间,或者CData Section内包含的普通文本。这个节点不能包含子节点。
l CDataSection——<![CDATA[]]>的对象表现形式。这个节点类型仅能包含文本节点Text作为子节点。
l Entity——表示在DTD中的一个实体定义。如<!ENTITY foo “foo”>。这个节点不能包含子节点。
l EntityReference——代表一个实体引用,例如"。这个节点不能包含子节点。
l ProcessingInstruction——代表一个PI。这个节点不能包含子节点。
l Comment——代表XML注释。这个节点不能包含子节点。
l Notation——代表在DTD中定义的记号。
Node接口定义了对应不同节点类型的12个常量:
❑ Node.ELEMENT_NODE (1)
❑ Node.ATTRIBUTE_NODE (2)
❑ Node.TEXT_NODE (3)
❑ Node.CDATA_SECTION_NODE (4)
❑ Node.ENTITY_REFERENCE_NODE (5)
❑ Node.ENTITY_NODE (6)
❑ Node.PROCESSING_INSTRUCTION_NODE (7)
❑ Node.COMMENT_NODE (8)
❑ Node.DOCUMENT_NODE (9)
❑ Node.DOCUMENT_TYPE_NODE (10)
❑ Node.DOCUMENT_FRAGMENT_NODE (11)
❑ Node.NOTATION_NODE (12)
Node接口也定义了一些所有节点类型都包含的特性和方法:
特性/方法 | 类型/返回类型 | 说明 |
nodeName | String | 节点的名字,根据节点的类型而定义 |
nodeValue | String | 节点的值,根据节点的类型而定义 |
nodeType | Number | 节点的类型常量值之一 |
ownerDocument | Document | 指向这个节点所属的文档 |
firstChild | Node | 指向在childNodes列表中的第一个节点 |
lastChild | Node | 指向在childNodes列表中的最后一个节点 |
childNodes | NodeList | 所有子节点的列表 |
previousSibling | Node | 指向前一个兄弟节点,如果这个节点就是第一个兄弟节点,那么该值为null |
nextSibling | Node | 指向后一个兄弟节点,如果这个节点就是最后一个兄弟节点,那么该值为null |
hasChildNodes() | Boolean | 当childNodes包含一个或多个节点时,返回true |
attributes | NamedNodeMap | 包含了代表一个元素的特性的Attr对象,仅用于Element节点 |
appendChild(node) | Node | 将node添加到childNodes的末尾 |
removeChild(node) | Node | 从childNodes中删除node |
replaceChild(newnode,oldnode) | Node | 将childNodes中的oldnode替换成newnode |
insertBefore(newnode,refnode) | Node | 将childNodes中的refnode之前插入newnode |
DOM还定义了一些助手对象,他们可以和节点一起使用,但不是DOM文档必有的部分:
l NodeList——节点数组,按数值进行索引,用来表示一个元素的子节点。
l NamedNodeMap——同时用数值和名字进行索引的节点表,用于表示元素特性。
6.2 使用DOM
JavaScript中大部分处理DOM的过程都是利用document对象。
6.2.1 访问相关的节点
要访问<html/>元素,可以使用document的documentElement特性:
var oHtml=document.documentElement
要去的<head/>和<body/>可以使用:
var oHead=oHtml.firstChild;
var oBody=oHtml.lastChild;
也可以使用childNodes特性来完成:
var oHead=oHtml.childNodes[0];
var oBody=oHtml.childNodes[1];
可以用childNodes.length来获取子节点的数量
6.2.2 处理特性
只有Element节点才有特性,该节点的attributes属性其实是NamedNodeMap,它提供了一些用于访问和处理其内容的方法:
l getNamedItem(name)——返回nodeName属性值等于name的节点。
l removeNamedItem(name)——删除nodeName属性值等于name的节点。
l setNamedItem(node)——将node添加到列表中,按其nodeName属性进行索引。
l item(pos)——像NodeList一样,返回在位置pos的节点。
l getAttribute(name)——等于attributes.getNamedItem(name).value。
l setAttribute(name,newvalue)——等于attributes.getNamedItem(name).value=newvalue。
l removeAttribute(name)——等于attributes. removeNamedItem(name)。
这些方法都返回一个Attr节点,而非特性值。
当NamedNodeMap用于表示特性时,其中每个节点都是Attr节点,它的nodeName属性被设置为特性名称,而nodeName属性被设置为特性值。
6.2.3 访问指定节点
1.getElementsByTagName()——返回一个包含所有tagname(标签名)特性等于某个指定值的元素的NodeList。并可用方括号或item()方法逐个访问这些节点。
2.getElementsByName()——获取所有name特性等于指定值的元素。
3.getElementsById()——返回id特性等于指定值的元素。这是在文档中获取单个指定元素最快的方法。
6.2.4 创建和操作节点
l creatComment(text)——创建包含文本text的注释节点
l createDocumentFragment()——创建文档碎片节点
l createElement(tagname)——创建标签名为tagname的元素
l createTextNode(text)——创建包含文本text的文本节点
6.3 HTML DOM特征功能
6.3.1 特性与属性一样
HTML DOM元素中包含的所有特性都是可作为属性。
你可以用下面方式:
oImg.getAttribute(“src”)或oImg.src
唯一特性和属性名不一样的是class特性,它是用来指定应用于某个元素的一个CSS类的。所以相应的属性名为className。
6.3.2 table方法
为避免创建表格的代码冗长,HTML DOM给<table/>、<tbody/>、<tr/>添加了一些特性和方法。
给<table/>元素添加了一下内容
❑ caption —指向<caption/> 元素(如果存在)
❑ tBodies —<tbody/>元素的集合
❑ tFoot —指向<tfoot/>元素(如果存在)
❑ tHead —指向<thead/>元素(如果存在)
❑ rows —表格中所有行的集合
❑ createTHead() —创建<thead/>元素并将其放入表格
❑ createTFoot() —创建<tfoot/>元素并将其放入表格
❑ createCaption() —创建<caption/>元素并将其放入表格
❑ deleteTHead() —删除<thead/>元素
❑ deleteTFoot() —删除<tfoot/>元素
❑ deleteCaption() —删除<caption/>元素
❑ deleteRow(position) —删除指定位置上的行
❑ insertRow(position) —在rows集合中的指定位置上插入一个新行
给<tbody/>元素添加了一下内容:
❑ rows —<tbody/>中所有行的集合
❑ deleteRow(position) —删除指定位置上的行
❑ insertRow(position) —在rows集合中的指定位置上插入一个新行
给<tr/>元素添加了一下内容:
❑ cells —<tr/>元素中所有的单元格的集合
❑ deleteCell(position) —删除给定位置上的单元格
❑ insertCell(position) —在cells集合的给定位置上插入一个新的单元格
6.4 小结
介绍了DOM的基本接口。了解到DOM如何将基于XML的文档组织成由任意节点组成的层次树。介绍了在文档中出现的不同的节点类型以及如何处理、添加、删除DOM树中的节点。