DOM2和DOM3

DOM1主要定义了HTML和XML文档的底层结构。

DOM2和DOM3在这些结构上加入了更多交互能力,提供更高级的XML特性。

分模块,模式如下:

DOM Core:在DOM1核心部分的基础上,为节点增加方法和属性。

DOM Views:定义基础样式信息和不同视图。

DOM Events:定义通过事件实现DOM文档交互。

DOM Style:定义以编程方式访问和修改CSS样式的接口。

DOM Traversal and Range:新增便利DOM文档及选择文档内容的接口。

DOM HTML:在DOM1 HTML部分的基础上,增加属性、方法和新接口。

DOM Mutation Observers:定义给予DOM变化触发回调的接口。

DOM3还有XPath模块和Load and Save模块。

XML命名空间

命名空间使用xmlns指定,XHTML的命名空间是http://www.w3.org/1999/xhtml,应该包含在任何格式规范的XHTML页面的<html>元素中。

遍历DOM节点

DOM2 Traversal and Range模块定义了两个类型用于辅助顺序变量DOM结构。NodeIterator和TreeWalker,从某个起点开始执行对DOM结构的深度优先遍历。

NodeIterator

可以通过document.createNodeIterator()方法创建其实例,接收四个参数:

root,作为遍历根节点的节点。

whatToShow,数值代码,表示应该访问哪些节点。

Filter,NodeFilter对象或函数,表示是否接收或跳过特定节点。

entityReferenceExpansion,布尔值,表示是否扩展实体引用。这个参数在HTML文档中没有效果,因为实体引用永远不扩展。

whatToShow参数是一个位掩码。

除了NodeFilter.SHOW_ALL之外,都可以组合使用。可以像下面这样使用按位或操作组合多个选项。

let whatToShow=NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT;

NodeFilter对象只有一个方法acceptNode(),如果给定节点应该访问九返回NodeFilter.FILTER_ACCEPT,否则返回NodeFilter.FILTER_SKIP。

定义一个只接收<p>元素的节点过滤器对象:

let filter ={
	acceptNode(node){
		return node.tagName.toLowerCase()==='p'?
			NodeFilter.FILTER_ACCEPT :
			NodeFilter.FILTER_SKIP;
	}
};
let iterator =document.createNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);

let node=iterator.nextNode();
let node=iterator.previousNode();
TreeWalker

TresWalker是NodeIterator的高级版。

其还添加了如下在DOM结构中向不同方向遍历的方法。

  • parentNode(),遍历到当前节点的父节点。
  • firstChild(),遍历到当前节点的第一个子节点。
  • lastChild(),遍历到当前节点的最后一个子节点。
  • nextSibling(),遍历到当前节点的下一个同胞节点。
  • previousSibling(),遍历到当前节点的上一个同胞节点。

用法如下:

let div=document.getElementById("div1")
let filter ={
	acceptNode(node){
		return node.tagName.toLowerCase()==='p'?
			NodeFilter.FILTER_ACCEPT :
			NodeFilter.FILTER_SKIP;
	}
};
let iterator =document.createTreeWalker(div,NodeFilter.SHOW_ELEMENT,filter,false);

let node=iterator.nextNode();
let node=iterator.previousNode();

范围

范围用于在文档中选择内容,而不用考虑节点之间的界限。

DOM范围

DOM2在document类型上定义了一个createRange()方法,可以创建一个DOM范围对象。

let range = document.createRange()
简单选择

使用selectNode()selectNodeContents()方法。

selectNode()方法选择整个节点,包括其后代节点。

selectNodeContents()只选择节点的后代。