《 JavaScript高级程序设计》第六章DOM基础知识介绍

《 JavaScript高级程序设计》第六章DOM基础知识介绍

截取自读书频道:

http://book.csdn.net/bookfiles/110/index.htm

6.1 什么是DOM

在开始详细介绍什么是DOM之前,你首先要了解是什么促使了它的诞生。尽管DOM很大程度上受到浏览器中动态HTML发展的影响,但W3C还是将它最先应用于XML

6.1.1 XML简介

XML可扩展标记语言)是从称为SGML标准通用标记语言)的更加古老的语言派生出来的。SGML的主要目的是定义使用标签来表示数据的标记语言的语法。

XML去掉了之前令许多开发人员头疼的SGML的随意语法。

1 任何的起始标签都必须有一个结束标签。

2 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<tag />XML解析器会将其翻译成<tag></tag>

3 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如<b>this is a <i>sample</i> string</b>

4 所有的特性都必须有值。

5 所有的特性都必须在值的周围加上双引号。

xml的主要目的是使用文本以结构化的方式来表示数据。在某些方面,XML文件也类似于数据库,提供数据的结构化视图。

每个XML文档都由XML序言开始,在前面的代码中的第一行便是XML序言<?xml version="1.0"?>

第二行代码,<books>,则是文档元素document element),它是文件中最外面的标签(我们认为元素(element)是起始标签和结束标签之间的内容)。

然后其中的具体内容就可能包括注释,处理指令,<![CDATA[ ]]>代码.

6.1.2 针对XMLAPI

XML定义为一种语言之后,就出现了使用常见的编程语言(如Java)来同时表现和处理XML代码的需求。

首先出现的是Java上的SAXSimple API for XML)项目。SAX提供了一个基于事件的XML解析的API。从其本质上来说,SAX解析器从文件的开头出发,从前向后解析,每当遇到起始标签或者结束标签、特性、文本或者其他的XML语法时,就会触发一个事件。然后,当事件发生时,具体要怎么做就由开发人员决定。

DOM是针对XML的基于树的API。它关注的不仅仅是解析XML代码,而是使用一系列互相关联的对象来表示这些代码,而这些对象可以被修改且无需重新解析代码就能直接访问它们。DOM是语言无关的API,他没有与某种语言绑定。

6.1.3 点的层次

DOM定义Node的接口以及许多种节点类型来表示XML节点的多个方面:

1 Document——最顶层的节点,所有的其他节点都是附属于它的。

2 DocumentType——DTD引用(使用<!DOCTYPE >语法)的对象表现形式,例如<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">。它不能包含子节点。

3 DocumentFragment——可以像Document一样来保存其他节点。

4 Element——表示起始标签和结束标签之间的内容,例如<tag></tag>或者<tag/>。这是唯一可以同时包含特性和子节点的节点类型。

5 Attr——代表一对特性名和特性值。这个节点类型不能包含子节点。

6 Text——代表XML文档中的在起始标签和结束标签之间,或者CData Section内包含的普通文本。这个节点类型不能包含子节点。

8 CDataSection——<![CDATA[ ]]>的对象表现形式。这个节点类型仅能包含文本节点Text作为子节点。

9 Entity——表示在DTD中的一个实体定义,例如<!ENTITY foo "foo">。这个节点类型不能包含子节点。

10 EntityReference——代表一个实体引用,例如&quot;这个节点类型不能包含子节点。

11 ProcessingInstruction——代表一个PI。这个节点类型不能包含子节点。

12 Comment——代表XML注释。这个节点类型不能包含子节点。

13 《 JavaScript高级程序设计》第六章DOM基础知识介绍Notation——代表在DTD中定义的记号。这个很少用到,所以在本书中不会讨论。

Node接口定义了对应不同节点类型的12个常量(它们会在即将讨论的nodeType特性中使用到):

1 Node.ELEMENT_NODE (1)

2 Node.ATTRIBUTE_NODE (2)

3 Node.TEXT_NODE (3)

4 Node.CDATA_SECTION_NODE (4)

5 Node.ENTITY_REFERENCE_NODE (5)

6 Node.ENTITY_NODE (6)

7 Node.PROCESSING_INSTRUCTION_NODE (7)

8 Node.COMMENT_NODE (8)

9 Node.DOCUMENT_NODE (9)

10 Node.DOCUMENT_TYPE_NODE (10)

11 Node.DOCUMENT_FRAGMENT_NODE (11)

12 Node.NOTATION_NODE (12)

Node接口也定义了一些所有节点类型都包含的特性和方法。我们在下面的表格中列出了这些特性和方法:

 

 

特性/方法

类型/返回类型

nodeName

String

节点的名字;根据节点的类型而定义

nodeValue

String

节点的值;根据节点的类型而定义

nodeType

Number

节点的类型常量值之一

ownerDocument

Document

指向这个节点所属的文档

firstChild

Node

指向在childNodes列表中的第一个节点

lastChild

Node

指向在childNodes列表中的最后一个节点

childNodes

NodeList

所有子节点的列表

《 JavaScript高级程序设计》第六章DOM基础知识介绍previousSibling

Node

指向前一个兄弟节点;如果这个节点就是第一个兄弟节点,那么该值为null

nextSibling

Node

指向后一个兄弟节点;如果这个节点就是最后一个兄弟节点,那么该值为null

hasChildNodes()

Boolean

childNodes包含一个或多个节点时,返回真

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文档必有的部分。

1 NodeList——节点数组,按照数值进行索引;用来表示一个元素的子节点。

2 NamedNodeMap——同时用数值和名字进行索引的节点表;用于表示元素特性。

6.1.4 特定语言的DOM

任何基于XML的语言,如XHTMLSVG,因为它们从技术上来说还是XML,仍然可以利用刚刚介绍的核心DOM。然而,很多语言会继续定义它们自己的DOM来扩展XML核心以提供语言的特色功能。

6.2 DOM的支持

并不是所有的浏览器对DOM的支持都一样。一般来说,MozillaDOM标准支持最好,

这个领域中落在最后的是IE,它对DOM Level 1的实现都还不完整,尚有很多方面有待完善。

6.3 使用DOM

document对象是BOM的一部分,同时也是HTML DOMHTMLDocument对象的一种表现形式,反过来说,它也是XML DOM Document对象

6.3.1 访问节点

在下面的几节中考虑下面的HTML页面:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

要访问<html/>元素(你应该明白这是该文件的document元素),你可以使用documentdocumentElement特性:

var oHtml = document.documentElement;

现在变量oHtml包含一个表示<html/>HTMLElement对象。如果你想取得<head/><body/>元素,下面的可以实现:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

也可以使用childNodes特性来完成同样的工作。只需把它当成普通的JavaScript Array,使用方括号标记:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

你还可以通过使用childNodes.length特性来获取子节点的数量:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

注意方括号标记其实是NodeListJavaScript中的简便实现。实际上正式的从childNodes列表中获取子节点的方法是使用item()方法:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

HTML DOM页定义了document.body作为指向<body/>元素的指针:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

有了oHtmloHeadoBody这三个变量,就可以先尝试确定它们之间的关系:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

这一小段代码测试并验证了oBodyoHeadparentNode特性都是指向oHtml变量,同时使用previousSiblingnextSibling特性来建立它们之间的关系。最后一行确认了oHeadownerDocument特性事实上是指向该文档。

6.3.2 检测节点类型

我们可以通过使用nodeType特性检验节点类型:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

这个例子中,document.nodeType返回9,等于Node.DOCUMENT_NODE;同时document. documentElement.nodeType返回1,等于Node.ELEMENT_NODE

也可以用Node常量来匹配这些值:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

这段代码可以在Mozilla 1.0+Opera 7.0+Safari 1.0+上正常运行。不幸的是,IE不支持这些常量,所以这些代码在IE上会产生错误。所幸,可以通过定义匹配节点类型的常量来纠正这种情况,正如下面这样:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

6.3.3 处理特性

只有Element节点才能有特性。Element节点的attributes属性其实是NamedNodeMap,它提供一些用于访问和处理其内容的方法:

1 getNamedItem(name)——返回nodeName性值等于name的节点;

2 removeNamedItem(name)——删除nodeName性值等于name的节点;

3 setNamedItem(node)——将node添加到列表中,按其nodeName性进行索引;

4 《 JavaScript高级程序设计》第六章DOM基础知识介绍item(pos)——像NodeList一样,返回在位置pos的节点;

NamedNodeMap对象也有一个length属性来指示它所包含的节点的数量。

NamedNodeMap用于表示特性时,其中每个节点都是Attr节点,它的nodeName性被设置为特性名称,而nodeValue性被设置为特性的值。例如,假设有这样一个元素:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

同时,假设变量oP包含指向这个元素的一个引用。于是可以这样访问id特性的值:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

还可以通过给nodeValue性赋新值来改变id性:

《 JavaScript高级程序设计》第六章DOM基础知识介绍

Attr节点也有一个完全等同于(同时也完全同步于)nodeValue属性的value属性,并且有name属性和nodeName属性保持同步。我们可以随意使用这些属性来修改或变更特性。

因为这个方法有些累赘,DOM又定义了三个元素方法来帮助访问特性:

q