DOM1级主要定义了HTML和XML文档的底层结构,DOM2和DOM3则在DOM1的基础上引入了更多的交互功能,支持了更高级的XML特性。DOM2和DOM3分为许多模块(模块之间具有某种联系),这些模块如下:
DOM2级核心:在1级核心基础上,为节点添加了更多方法和属性。
DOM2级视图:为文档定义了基于样式信息的不同视图
DOM2级HTML:在1级HTML基础上构建,添加了更多属性、方法和新接口
DOM2级样式:定义了如何以编程方式来访问和改变CSS样式信息
DOM2级遍历和范围:引入了遍历DOM文档和选择其特定部分的新接口
DOM2级事件:说明了如何以编程方式来访问和改变CSS样式
DOM3级XPath
DOM3级加载与保存
一、DOM的变化
(一)针对xml命名空间的变化
有了XML命名空间,不同XML文档的元素就可以混合在一起,共同构成格式良好的文档,而不必担心发生命名冲突。从技术上说,HTML不支持XML命名空间,但XHTML支持XML命名空间。
在此,先不讨论针对xml命名空间的变化,后续有需要再进行更新。
(二)其他方面的变化
其他方面的变化与XML命名空间无关,这些变化是为了确保API的可靠性及完整性
1、DocumentType类型的变化
DocumentType类型新增了3个属性(在网页中很少需要使用以下三个属性访问此类信息):
publicId
systemId
internalSubset
2、Document类型的变化
3、Node类型的变化
4、框架的变化
二、样式
(一)访问元素的样式
1、DOM style属性的属性和方法
DOM2级样式规范为style对象定义了一些属性和方法:
cssText:返回style属性中的CSS代码
length:HTML元素的style属性中包含的CSS属性的个数
item(index):
getPropertyValue(propertyName)
getPropertyCSSValue(propertyName):返回一个CSSValue(实际开发中用得很少)
getPropertyPriority(propertyName):若属性使用了!important设置,则返回"!important";否则,返回空字符串
removeProperty(propertyName)
setProperty(propertyName,value,priority):参数priority的取值为"!important"或空字符串
parentRule:表示CSS信息的CSSRule对象
2、计算的样式
元素的style对象只包含通过style属性设置的样式信息,不包含其他样式表中的信息。为了得到应用在当前元素的所有样式,DOM2级增加了document.defaultView属性,并为该属性提供了getComputedStyle()方法。
语法:document.default.getComputedStyle(要取得样式的元素, 伪元素字符串)(伪元素字符串如:":after",若不需要伪元素信息,则该参数为null)
getComputedStyle()返回一个CSSStyleDeclaration对象,包含应用在当前元素的所有样式。
var div = document.getElementById("#myDiv");
var computedStyle = document.defaultView.getComputedSytle(div,null);
IE不支持getComputedStyle(),但它为每个支持style属性的元素指定了currentStyle属性,这个属性返回一个CSSStyleDeclaration对象。
var div = document.getElementById("#myDiv");
var computedStyle = div.currentStyle;
(二)操作样式表
可以用CSSStyleSheet类型来表示样式表,它包括<link>元素包含的样式表和<style>元素中定义的样式表。
DOM2级定义了获取样式表的属性,返回CSSStyleSheet对象,该对象是一套只读的接口。
document.styleSheets返回的是应用于文档的所有样式表的对象集合
-
还可以通过<link>或<style>元素直接获取CSSStyleSheet对象,获取的方式是使用sheet属性(非IE),或styleSheet属性(IE)
function getStyleSheet(element){ return element.sheet || element.styleSheet; } //获取第一<link>元素引入的样式表 var link = document.getElementsByTagName("link")[0] var sheet = getStyleSheet(link);
1、CSS规则
CSSRule表示样式表中的每一条规则。其实,CSSRule是一个供其他多种类型继承的基类型,其中最常见的是CSSStyleRule,表示样式信息。CSSStyleRule对象包含下列属性:
(1) cssText:返回整条规则对应的文本(包括CSS选择符和花括号)
(2)selectorText:返回当前规则的选择符
(3)style:一个CSSStyleDeclaration对象(style.cssText返回规则中所有的CSS样式)
(4)parentRule:
(5)parentStyleSheet:当前规则所属的样式表
(6)type:表示规则类型的常量值。
上述属性中,前三个常用。
2、创建规则
使用insertRule()可以向现有样式表中添加新规则
-
语法:sheet.insertRule(规则文本,插入规则的位置)
sheet.insertRule("body{background-color:silver;}",0);
-
IE8及更早版本支持一个类似的方法:addRule(选择符文本,CSS样式信息,插入规则的位置)
sheet.addRule("body","background-color:silver",0);
若要添加的规则非常多,请使用动态加载样式表的技术
3、删除规则
若要删除某天规则,请使用deleteRule(index)
sheet.deleteRule(0) //IE之外的浏览器
sheet.removeRule(0) //IE
//跨浏览器删除规则的函数
function deleteRule(sheet, index){
if(sheet.deleteRule){
sheet.deleteRule(index);
}
else if(sheet.removeRule){
sheet.removeRule(index);
}
}
请慎用删除规则的方法
(三)元素的大小
下面介绍的属性和方法并不属于“DOM2级样式”规范,但却与HTML元素的样式息息相关。
1、偏移量
元素的偏移量涉及4个属性(这些偏移量属性都是只读的,每次访问都会重新计算):
offsetHeight:包含可见的垂直滚动条高度
offsetWidth:包含可见的垂直滚动条宽度
offsetLeft
offsetTop
下图反映了上述4个属性的表示范围:
2、客户区大小
客户区大小指的是,元素内容及其内边距所占据的空间大小(不包括滚动条及边框)
与客户区大小有关的属性有两个:
clientWidth
clientHeight
下图反映了上述两个属性的表示范围:
三、范围
DOM2级为Document类型定义了createRange()方法,该方法可以创建范围:
var range = document.createRange();
每一个范围由一个Range类型的实例表示,该实例拥有很多属性和方法,下列属性提供了当前范围在文档中的位置信息:
startContainer:选区中第一个节点的父节点
startOffset:范围中第一个子节点的索引
endContainer:选区中最后一个节点的父节点
endOffset:范围中最后一个子节点的索引
commonAncestorContainer
(一)用范围实现简单选择
以下方法可以实现选择文档中的一部分:
selectNode(DOM节点):选择整个DOM节点
selectNodeContents(DOM节点):只选择节点的子节点
setStartBefore(redNode):将范围的七点设置在refNode之前
setStartAfter(refNode):将范围的起点设置在refNode之后
setEndBefore(refNode):将范围的终点设置在refNode之前
setEndAfter(refNode):将范围的终点设置在refNode之后
(二)用DOM范围实现复杂选择
DOM2级创建的范围,不仅能够选择节点,还能够选择节点的一部分,使用下面两个方法可以完成这种操作:
setStart(参照节点,偏移量)
setEnd(参照节点,偏移量)
例如有如下HTML代码:
<!DOCTYPE html>
<html lang="en">
<body>
<p id="p1"><b>Hello</b> world!</p>
</body>
</html>
我们想从“Hello world!”中选取“llo wo”,代码如下:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
利用范围选择了文档的某一部分,接下来便可以对选择的部分进行操作。
(三)操作DOM范围中的内容
在上述的例子中,范围会自动为自身添加相应的HTML标签,上例创建范围完成后的HTML代码如下:
<p><b>He</b><b>llo</b> world!</p>
这样创建范围后,就可以使用各种方法对范围的内容进行操作了
1、deleteContents():从文档中删除范围包含的内容
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
range.deleteContents();
运行上述代码后输出结果:
2、extractContents():从文档中移除范围选区,并返回范围的文档片段
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
var fragement = range.extractContents();
p1.parentNode.appendChild(fragement);
运行上述代码后输出结果:
3、cloneContents():创建范围对象的一个副本
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
var fragement = range.cloneContents();
p1.parentNode.appendChild(fragement);
运行上述代码后输出结果:
(四)向范围中插入内容
1、insertNode():向范围选区的开始处插入一个节点
假设向前面例子中的范围前插入以下HTML代码:
<span style="color:red">Inserted text</span>
则js代码如下:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);
var span = document.creatElement("span");
span.style.color = "red";
span.appendChild(document.createTextNode("Inserted text"));
range.insertNode(span);
运行上述代码后输出结果:
2、surroundContents(环绕范围内容的节点):环绕范围插入内容
利用该方法可以突出显示网页中的某些词句,代码如下:
var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChid;
var worldNode = p1.lastChid;
var range = document.createRange();
range.selectNode(helloNode);
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
代码运行的结果如下:
(五)折叠范围
折叠范围,就是指范围中未选择文档的任何部分。
-
collapse()方法可以折叠范围,该方法接受一个布尔值的参数:
参数取值为true:折叠到范围的起点
参数取值为false:折叠到范围的终点
collapse属性可以检测范围是否处于折叠状态
(六)比较范围
compareBoundaryPoints()方法可以比较多个范围的起点(或终点)
-
该方法接受两个参数:
-
表示比较方式的常量(有以下四个取值)
Range.START_TO_START:比较第一个范围和第二个范围的起点
Range.START_TO_END
Range.END_TO_END
Range.END_TO_START
要比较的范围
-
-
该方法有三个可能的返回值:
返回-1:第一个范围中的点位于第二个范围中的点之前
返回0:两个点相等
返回1:第一个范围中的点位于第二个范围中的点之后
(七)复制范围
cloneRange()方法可以复制范围
var newRange = range.cloneRange();
以上代码创建了一个range的副本,newRange与range有相同的属性,修改newRange不会影响原来的范围。
(八)清理范围
在使用完范围后,最好是从创建范围的文档中分离出该范围,从而可以让垃圾回收机制回收其内存。
range.detach(); //从文档中分离
range = null; //解除引用
推荐在使用完范围后再执行上述两个步骤。