第12章 DOM2和DOM3
DOM1级主要定义的是HTML和XML文档的底层结构。DOM2和DOM3级则在这个结构的基础上引入了更多的交互能力,也支持了更高级的XML特性。
12.1 DOM变化
12.1.1 针对XML命名空间的变化
命名空间要使用xmlns特性来指定。XHTML的命名空间是http://www.w3.org/1999/xhtml,在任何格式良好的XHTML页面中,都应该将其包含在<html>元素中。
1.Node类型的变化
在DOM2级中,Node类型包含下列特定于命名空间的属性。
(1)localName:不带命名空间前缀的节点名称。
(2)namespaceURI:命名空间URI或者(在未指定的情况下是)null。
(3)prefix:命名空间前缀或者(在未指定的情况下是)null。
DOM3级在此基础上更进一步,又引入了下列与命名空间有关的方法。
(1)isDefaultNamespace(namespaceURI):在指定的namespaceURI是当前节点的默认命名空间的情况下返回true。
(2)lookupNamespaceURI(prefix):返回指定prefix的命名空间。
(3)lookupPrefix(namespaceURI):返回给定namespaceURI的前缀、
2.Doumnet类型的变化
3.Element类型变化
4.NameedNodeMap类型的变化
12.1.2其他方面的变化
1.DocumentType类型的变化
DocumentType类型新增了3个属性:publicId、systemId和internalSubset。
2.Document类型的变化
Document类型的变化中唯一与命名空间无关的方法是importNode()。用于从一个文档中取得一个节点,然后将其导入到另一个文档,使其成为这个文档结构的一部分。该方法接收两个参数:要复制的节点和一个表示是否复制子节点的布尔值。
3.Node类型的变化
Node类型中唯一与命名空间无关的变化,就是添加了isSupported()方法。与DOM1级为document.implementation引入的hasFeature()方法类似,isSupported()方法用于确定当前节点具有什么能力。这个方法也接受相同的两个参数:特性名和特性版本号。如果浏览器实现了相应特性,而且能够基于给定节点执行该特性,isSupported()就返回true。
4.框架的变化
框架和内嵌框架分别用HTMLFrameElement和HTMLFrameElement表示,它们在DOM2级中都有一个新属性,名叫contentDocument。这个属性包含一个指针,指向表示框架内容的文档对象。
12.2 样式
在HTML中定义样式的方式有3中:通过<link/>元素包含外部样式表文件、使用<style/>元素定义嵌入式样式,以及使用style特性定义针对特定元素的样式。
12.2.1 访问元素的样式
任何支持style特性的HTML元素在JavaScript中都有一个对应的style属性。这个style对象是CSSStyleDeclaration的实例,包含这通过HTML的style特性指定的样式信息,但不包括与外部样式表或嵌入式样式表经层叠而来的样式。在style特性中指定的任何CSS属性都将表现为style的相应属性。对于使用短划线(分隔不同的词汇,例如background-image)的CSS属性名,必须将其转换成驼峰大小写形式,才能通过JavaScript来访问。
1.DOM样式属性和方法
“DOM2级样式”规范还为style对象定义了一些属性和方法。这些属性和方法在提供元素的style特性值的同事,也可以修改样式。
通过cssText属性可以访问style特性中的CSS代码。在读取模式下,cssText返回浏览器对style特性中CSS代码的内部表示。在写入模式下,赋给cssText的值会重写整个style特性的值;也就是说,以前通过style特性指定的样式信息都将丢失。
要从元素的样式中移除某个CSS属性,需要使用removeProperty()方法。使用这个方法移除一个属性,意味着将会为该属性应用默认的样式(从其他样式表经层叠而来)。
2.计算的样式
虽然style对象能够提供支持style特性的任何元素的样式信息,但它不包含那些从其他样式表层叠而来并影响到当前元素的样式信息。
12.2.2 操作样式表
CSSStyleSheet类型表示的是样式表,包括通过<link>元素包含的样式表和在<style>元素中定义的样式表。这两个元素本身粉笔是由HTMLLineElement和HTMLStyleElement类型表示的。
1.CSS规则
CSSRule对象表示样式表中的每一条规则。实际上,CSSRule是一个供其他多种类型继承的基类型,其中最常见的就是CSSStyleRule类型,表示样式信息(其他规则还有@import、@font-face、@page和@charset,但是这些规则很少有必要通过脚本来访问)。
2.创建规则
DOM规定,要向现有的样式表中添加新规则,需要使用insertRule方法。这个方法接受两个参数:规则文本和表示在哪里插入规则的索引。
3.删除规则
从样式表中删除规则的方法是deleteRule(),这个方法接受一个参数:要删除的规则的位置。
12.2.3 元素大小
DOM中没有规定如何确定页面中元素的大小。IE为此率先引入了一些属性,以便开发人员使用。目前,所有主要的浏览器都已经支持这些属性。
1.偏移量
通过以下4个属性可以取得元素的偏移量。
(1)offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。
(2)offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。
(3)offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。
(4)offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。
注意:所有这些偏移量的属性都是只读的,而且每次访问它们都需要重新计算。因此,应该尽量避免重复访问这些属性;如果需要重复使用其中的某些属性的值,可以将它们保存在局部变量中,以提高性能。
2.客户区大小
元素的客户区大小(client dimension),指的是元素内容及其内边距所占据的空间大小。有关客户区大小的属性有两个:clientWidth和clientHeight。其中clientWidth在属性是元素内容区宽度加上左右内边距的宽度;clientHeight属性是元素内容区高度加上上下内边距的高度。
3.滚动大小
滚动大小(scroll dimension),指的是包含滚动内容的元素的大小。
以下是4个与滚动大小相关的属性。
(1)scrollHeight:在没有滚动条的情况下,元素内容的总高度。
(2)scrollWidth:在没有滚动条的情况下,元素内容的总宽度。
(3)scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。
(4)scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。
4.确定元素的大小
IE、Firefox3+、Safari4+、Opera9.5及Chrome为每个元素都提供一个getBoundingClientRect()方法。这个方法返回一个矩形对象,包含4个属性:left、top、right和bottom。这个属性给出了元素在页面中相对于视口的位置。
12.3 遍历
“DOM2级遍历和范围”模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIterator和TreeWalker。这两个类型能够基于给定的起点对DOM结构执行深度优先(depth-first)的遍历操作。
12.3.1 NodeIterator
NodeIterator类型是两者中比较简单的一个,可以使用document.createNodeIterator()方法创建它的新实例。这个方法接受下列4个参数。
(1)root:想要作为搜索起点的树中的节点。
(2)whatToShow:表示要访问哪些节点的数字代码。
(3)filter:是一个NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数。
(4)entityReferenceExpansion:布尔值,表示是否要扩展实体引用。这个参数在HTML页面中没有用,因为其中的实体引用不能扩展。
NodeIterator类型的两个主要方法是nextNode()和previousNode()。顾名思义,在深度优先的DOM子树遍历中,nextNode()方法用于向前前进一步,而previousNode()用于向后后退一步。
12.3.2 TreeWalker
TreeWalker是NodeIterator的一个更高级的版本。除了包括nextNode()和previousNode()在内的相同的功能之外,这个类型还提供了下列用于在不同方向上遍历DOM结构的方法,
(1)parentNode():遍历到当前节点的父节点。
(2)firstChild():遍历到当前节点的第一个子节点。
(3)lastChild():遍历到当前节点的最后一个节点。
(4)nextSibling():遍历到当前节点的下一个同辈节点。
(5)previousSibling():遍历到当前节点的上一个同辈节点。
12.4 范围
为了让开发人员更方便第控制页面,“DOM2级遍历和范围”模块定义了“范围”(range)接口。通过范围可以选择文档中的一个区域,而不必考虑节点的界限(选择在后台完成,对用户是不可见的)。
12.4.1 DOM中的范围
DOM2级在Document类型中定义了createRange()方法。在兼容DOM的浏览器中,这个方法属于document对象。使用hasFeature()或者直接检测该方法,都可以确定浏览器是否支持范围。
12.4.2 IE8及更早版本中的范围
虽然IE9支持DOM范围,但IE8及之前版本不支持DOM范围。不过,IE8及早期版本支持一种类似的概念,即文本范围(text range)。文本范围是IE专有的特性,其他浏览器都不支持。顾名思义,文本范围处理的主要是文本(不一定是DOM节点)。通过<body>、<button>、<input>、和<textarea>等这几个元素,可以调用createTextRange()方法来创建文本范围。