第12章 DOM2和DOM3
- DOM2 级核心(DOM Level 2 Core):在 1 级核心基础上构建,为节点添加了更多方法和属性。
- DOM2 级视图(DOM Level 2 Views):为文档定义了基于样式信息的不同视图。
- DOM2 级事件(DOM Level 2 Events):说明了如何使用事件与 DOM 文档交互。
- DOM2 级样式(DOM Level 2 Style):定义了如何以编程方式来访问和改变 CSS 样式信息。
- DOM2 级遍历和范围(DOM Level 2 Traversal and Range):引入了遍历 DOM 文档和选择其特定
部分的新接口。- DOM2 级 HTML(DOM Level 2 HTML):在 1 级 HTML 基础上构建,添加了更多属性、方法和新接口。
可以通过下列代码来确定浏览器是否支持这些 DOM 模块。
var supportsDOM2Core = document.implementation.hasFeature("Core", "2.0");
var supportsDOM3Core = document.implementation.hasFeature("Core", "3.0");
var supportsDOM2HTML = document.implementation.hasFeature("HTML", "2.0");
var supportsDOM2Views = document.implementation.hasFeature("Views", "2.0");
var supportsDOM2XML = document.implementation.hasFeature("XML", "2.0");
1. DOM 变化
DOM2 级和 3 级的目的在于扩展 DOM API,以满足操作 XML 的所有需求,同时提供更好的错误处理及特性检测能力。从某种意义上讲,实现这一目的很大程度意味着
对命名空间的支持
。
- DOM2 级核 心”没有引入新类型,它只是在 DOM1 级的基础上通过增加新方法和新属性来增强了既有类型。
- “DOM3 级核心”同样增强了既有类型,但也引入了一些新类型。
(1) 针对XML命名空间的变化
- 有了 XML 命名空间,不同 XML 文档的元素就可以混合在一起,共同构成格式良好的文档,而不必担心发生命名冲突。
- HTML 不支持 XML 命名空间,但
XHTML
支持 XML 命名空间。命名空间要使用 xmlns 特性来指定
。- XHTML 的命名空间是 http://www.w3.org/1999/xhtml,在任何 格式良好 XHTML 页面中,都应该将其包含在元素中。
- 其中的所有元素默认都被视为 XHTML 命名空间中的元素。
Example XHTML page
Hello world!
- 要想明确地为 XML 命名空间创建前缀,可以使用 xmlns 后跟冒号,再后跟前缀。
Example XHTML page
//为了避免不同语言间的冲突,也需要使用命名空间来限定特性
Hello world!
- 在混合使用两种语言的情况下,命名空间的用处
Example XHTML page
* Node 类型的变化
- 在 DOM2 级中,Node 类型包含下列
特定于命名空间的属性
。
(1) localName: 不带命名空间前缀的节点名称。
(2) nameSpaceURI: 命名空间URI或者(在未指定的情况下是)null。
(3) prefix:命名空间前缀或者(在未指定的情况下是)null。
nodeName 等于 prefix+":"+ localName。
- DOM3 级在此基础上更进一步,又引入了下列与命名空间有关的方法。
(1) isDefaultNamespace(namespaceURI):在指定的 namespaceURI 是当前节点的默认命名空
间的情况下返回 true。
(2) lookupNamespaceURI(prefix):返回给定 prefix 的命名空间。
(3) lookupPrefix(namespaceURI):返回给定 namespaceURI 的前缀。
* Document 类型的变化
DOM2 级中的 Document 类型也发生了变化,包含了下列与命名空间有关的方法。
(1) createElementNS(namespaceURI, tagName):使用给定的 tagName 创建一个属于命名空 间 namespaceURI 的新元素。
(2) createAttributeNS(namespaceURI, attributeName):使用给定的 attributeName 创 建一个属于命名空间 namespaceURI 的新特性。
(3) getElementsByTagNameNS(namespaceURI, tagName):返回属于命名空间 namespaceURI 的 tagName 元素的 NodeList。
*Element 类型的变化
(1) getAttributeNS(namespaceURI,localName):取得属于命名空间 namespaceURI 且名为 localName 的特性。
(2) getAttributeNodeNS(namespaceURI,localName):取得属于命名空间 namespaceURI 且 名为 localName 的特性节点。
(3) getElementsByTagNameNS(namespaceURI, tagName):返回属于命名空间 namespaceURI 的 tagName 元素的 NodeList。
(4) hasAttributeNS(namespaceURI,localName):确定当前元素是否有一个名为 localName 的特性,而且该特性的命名空间是 namespaceURI。注意,“DOM2 级核心”也增加了一个 hasAttribute()方法,用于不考虑命名空间的情况。
(5) removeAttriubteNS(namespaceURI,localName):删除属于命名空间 namespaceURI 且名 为 localName 的特性。
(6) setAttributeNS(namespaceURI,qualifiedName,value):设置属于命名空间 namespace- URI 且名为 qualifiedName 的特性的值为 value。
(7) setAttributeNodeNS(attNode):设置属于命名空间 namespaceURI 的特性节点。
* NamedNodeMap 类型的变化
(1) getNamedItemNS(namespaceURI,localName):取得属于命名空间 namespaceURI 且名为
localName 的项。
(2) removeNamedItemNS(namespaceURI,localName):移除属于命名空间 namespaceURI 且名
为 localName 的项。
(3) setNamedItemNS(node):添加 node,这个节点已经事先指定了命名空间信息。
(2) 其他方面的变化
* DocumentType 类型的变化
DocumentType 类型新增了 3 个属性:publicId、systemId 和 internalSubset
。
- 前两 个属性表示的是文档类型声明中的两个信息段
属性 internalSubset
,用于访问包含在文档类型声明中的额外定义。
]>
alert(document.doctype.publicId);
// "-//W3C//DTD HTML 4.01//EN"
alert(document.doctype.systemId);
// "http: //www.w3.org/TR/html4/strict.dtd"
alert(document.doctype.internalSubset);
// ""
*Document 类型的变化
importNode()方法
:
- 这个方法的用途是从一个文档中取得一个节点,然后将其导入到另一个文档,使其成为这个文档结构的一部分。
- 每个节点都有一个
ownerDocument 属性
,表示所属的文档。如果调用 appendChild()时传入的节点属于不同的文档(ownerDocument 属性的值不一样),则会导致错误。但在调用 importNode()时传入 不同文档的节点则会返回一个新节点,这个新节点的所有权归当前文档所有。接受两个参数
:要复制的节点和一个表示是否复制子节点的布尔值。
//导入节点及其所有子节点
var newNode = document.importNode(oldNode, true);
document.body.appendChild(newNode);
defaultView 的属性
:
- DOM2 级视图”模块属性,其中保存着一个指针,
指向拥有给 定文档的窗口(或框架)
。- 在 IE 中有一个等价的属性名叫 parentWindow(Opera 也支持这个属性)。
var parentWindow = document.defaultView || document.parentWindow;
DOM2 级核心”还为document.implementation 对象
规定了 两个新方法:createDocumentType()
和 createDocument()
。
createDocumentType() 方法
: 于创建一个新的 DocumentType 节点,接受 3 个参数:文档类型名称、publicId、systemId。createDocument()方法
:3 个参数:针对文档中元素的 namespaceURI、文档元素的标签名、新文档的文档类型。
var doctype = document.implementation.createDocumentType(
"html",
" -//W3C//DTD XHTML 1.0 Strict//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
var doc = document.implementation.createDocument(
"http://www.w3.org/1999/xhtml",
"html",
doctype);
DOM2 级 HTML”模块也为 document.implementation
新增了一个方法,名叫 createHTMLDocument()
。
createHTMLDocument()方法
:这个方法的用途是创建一个完整的 HTML 文档,包括、、和 元素。这个方法只接受一个参数,即新创建文档的标题(放在元素中的字符串),返回 新的 HTML 文档
* Node 类型的变化
isSupported()方法
- DOM1 级为 document.implementation引入的hasFeature()方法类似。
- 用于确定当前节点具有 什么能力。这个方法也接受相同的两个参数:
特性名
和特性版本号
。如果浏览器实现了相应特性,而且能够基于给定节点执行该特性,isSupported()就返回 true。
DOM3 级引入了两个辅助比较节点的方法:isSameNode()
和 isEqualNode()
。
isSameNode()方法
接受 一个节点参数,并在传入节点与引用的节点相同时返回 true。isEqualNode()
接受 一个节点参数,并在传入节点与引用的节点等时返回 true。
//这里创建了两个具有相同特性的元素。这两个元素相等,但不相同。
var div1 = document.createElement("div");
div1.setAttribute("class", "box");
var div2 = document.createElement("div");
div2.setAttribute("class", "box");
alert(div1.isSameNode(div1)); //true
alert(div1.isEqualNode(div2)); //true
alert(div1.isSameNode(div2)); //false
(1) 所谓相同
,指的是两个节点引用的是同一个对象。
(2) 所谓相等
,指的是两个节点是相同的类型,具有相等的属性(nodeName、nodeValue, 等等),而且它们的 attributes 和 childNodes 属性也相等(相同位置包含相同的值)。
DOM3 级还针对为 DOM 节点添加额外数据引入了新方法。其中,setUserData()方法
会将数据指定给节点,它接受 3 个参数:要设置的键、实际的数据(可以是任何数据类型)和处理函数。
- 传入 setUserData()中的处理函数会在带有数据的节点被
复制、删除、重命名或引入一个文档时调用
,因而你可以事先决定在上述操作发生时如何处理用户数据。
- 处理函数接受
5 个参数
:表示操作类 型的数值(1 表示复制,2 表示导入,3 表示删除,4 表示重命名)、数据键、数据值、源节点和目标节点。
- 在删除节点时,源节点是 null;除在复制节点时,目标节点均为 null。在函数内部
var div = document.createElement("div");
div.setUserData("name", "Nicholas", function(operation, key, value, src, dest){
if (operation == 1){
dest.setUserData(key, value, function(){});
}
});
var newDiv = div.cloneNode(true);
alert(newDiv.getUserData("name")); //"Nicholas"
* 框架的变化
- 框架和内嵌框架分别用
HTMLFrameElement
和 HTMLIFrameElement
表示,它们在 DOM2 级中都有 了一个新属性,名叫 contentDocument
。这个属性包含一个指针,指向表示框架内容的文档对象。
- IE8 之前不支持框架中的 contentDocument 属性,但支持一个名叫
contentWindow
的属性,该属性返回框架的 window 对象,而这个 window 对象又有一个 document 属性。
var iframe = document.getElementById("myIframe");
var iframeDoc = iframe.contentDocument ||
iframe.contentWindow.document;
2. 样式
在 HTML 中定义样式的方式有 3 种:通过元素
包含外部样式表文件、使用元素
定义嵌入式样式,以及使用 style 特性
定义针对特定元素的样式。
确定浏览器是否支持 DOM2 级定义的 CSS 能力:
var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");
(1) 访问元素的样式
- 任何支持 style 特性的 HTML 元素在 JavaScript 中都有一个对应的 style 属性。
- 这个 style 对象 是
CSSStyleDeclaration 的实例
,包含着通过 HTML 的 style 特性指定的所有样式信息,但不包含与外部样式表或嵌入样式表经层叠而来的样式。
- 在 style 特性中指定的任何 CSS 属性都将表现为这个 style 对象的相应属性。
- 对于使用短划线(分隔不同的词汇,例如 background-image)的 CSS 属性 名,必须将其转换成
驼峰大小写形式
,才能通过 JavaScript 来访问。
- 由于
float
是 JavaScript 中的保留字,因此不能用作属性名。“DOM2 级样式”规范规定 样式对象上相应的属性名应该是 cssFloat
;Firefox、Safari、Opera 和 Chrome 都支持这个属性,而 IE 支持的则是 styleFloat。
* DOM 样式属性和方法
“DOM2 级样式”规范还为 style 对象定义了一些属性和方法。这些属性和方法在提供元素的 style特性值的同时,也可以修改样式。
(1) cssText:如前所述,通过它能够访问到 style 特性中的 CSS 代码。
(2) length:应用给元素的 CSS 属性的数量。
(3) parentRule:表示 CSS 信息的 CSSRule 对象。
(4) getPropertyCSSValue(propertyName):返回包含给定属性值的 CSSValue 对象。
(5) getPropertyPriority(propertyName):如果给定的属性使用了!important 设置,则返回"important";否则,返回空字符串。
(6) getPropertyValue(propertyName):返回给定属性的字符串值。
(7) item(index):返回给定位置的 CSS 属性的名称。
(8) removeProperty(propertyName):从样式中删除给定属性。
(9) setProperty(propertyName,value,priority):将给定属性设置为相应的值,并加上优先权标志("important"或者一个空字符串)。
在读取模式
下,cssText
返回浏览器对 style特性中 CSS 代码的内部表示。在写入模式
下,赋给 cssText 的值会重写整个 style 特性的值;也就是 说,以前通过 style 特性指定的样式信息都将丢失。
style 对象实际上就相当于一个集合,都可以使用方括号
语法来代替 item()
来取得给定位置的 CSS 属性。
var prop, value, i, len;
for (i=0, len=myDiv.style.length; i < len; i++){
prop = myDiv.style[i]; //或者 myDiv.style.item(i)
value = myDiv.style.getPropertyValue(prop);
alert(prop + " : " + value);
}
-
getPropertyCSSValue()方法
,它返回一个包含两个属性的 CSSValue 对象,这两个属性分别是:cssText
和 cssValueType
。
(1) cssText 属性
的值与 getPropertyValue()返回的值相同。
(2) cssValueType 属性
则是一个数值常量,表示值的类型:0 表示继承的值,1 表示基本的值,2 表示 值列表,3 表示自定义的值。
* 计算的样式
DOM2 级样式”增强了 document.defaultView,提供了 getComputedStyle()方法
。
- 这个方法接受
两个参数
:要取得计算样式的元素和一个伪元素字符串(例 如":after")。如果不需要伪元素信息,第二个参数可以是 null。
- getComputedStyle()方法返回一 个 CSSStyleDeclaration 对象(与 style 属性的类型相同),其中
包含当前元素的所有计算的样式
。
Computed Styles Example
var myDiv = document.getElementById("myDiv");
var computedStyle = document.defaultView.getComputedStyle(myDiv, null);
alert(computedStyle.backgroundColor);// "red"
alert(computedStyle.width);// "100px"
alert(computedStyle.height);// "200px"
alert(computedStyle.border);// 在某些浏览器中是"1px solid black"
- IE 不支持 getComputedStyle()方法,在 IE 中,每个具有 style 属性 的元素还有一个
currentStyle 属性
。这个属性是 CSSStyleDeclaration 的实例,包含当前元素全 部计算后的样式。
var myDiv = document.getElementById("myDiv");
var computedStyle = myDiv.currentStyle;
alert(computedStyle.backgroundColor);//"red"
alert(computedStyle.width);//"100px"
alert(computedStyle.height);//"200px"
alert(computedStyle.border);//undefined
* 所有计算的样式都是只读的;不能修改计算后样式对象中的 CSS 属性。
* 计算后的样式也包含属于浏览器内部样式表的样式信息,因此任何具有默认值 的 CSS 属性都会表现在计算后的样式中。
(2) 操作样式表
CSSStyleSheet 类型
表示的是样式表,包括通过元素
包含的样式表和在