DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
10.1 节点层次
文档元素是文档的最外层元素,文档中的其他所有元素都包含在文档元素中。每个文档只能有一个文档元素。
-
10.1.1 Node 类型
DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现。这个 Node 接口在 JavaScript 中是作为 Node 类型实现的;除了 IE 之外,在其他所有浏览器中都可以访问到这个类型。
每个节点都有一个 nodeType 属性,用于表明节点的类型。
-
- nodeName 和 nodeValue 属性
要了解节点的具体信息,可以使用 nodeName 和 nodeValue 这两个属性。
-
- 节点关系
文档中所有的节点之间都存在这样或那样的关系。节点间的各种关系可以用传统的家族关系来描 述,相当于把文档树比喻成家谱。
-
- 操作节点
最常用的方法是appendChild() ,用于向 childNodes 列表的末尾添加一个节点。 insertBefore() 方法,把节点放在 childNodes 列表中某个特定的位置上,而不是放在末尾。 replaceChild() 方法,要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。 removeChild() 方法, 移除的节点仍然为文档所有,只不过在文档中已经没有了自己的位置。
-
- 其他方法
cloneNode(),用于创建调用这个方法的节点的一个完全相同的副本。
-
-
10.1.2 Document 类型
JavaScript 通过 Document 类型表示文档。
-
10.1.3 Element 类型
Element 类型用于表现 XML或 HTML元素,提供了对元素标签名、子节点及特性的访问。
-
- HTML 元素
所有 HTML 元素都由 HTMLElement 类型表示,不是直接通过这个类型,也是通过它的子类型来表 示。 HTMLElement 类型直接继承自 Element 并添加了一些属性。添加的这些属性分别对应于每个HTML 元素中都存在的下列标准特性。
<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div> var div = document.getElementById("myDiv"); alert(div.id); //"myDiv"" alert(div.className); //"bd" alert(div.title); //"Body text" alert(div.lang); //"en" alert(div.dir); //"ltr" div.id = "someOtherId"; div.className = "ft"; div.title = "Some other text"; div.lang = "fr"; div.dir ="rtl";-
- 取得特性
每个元素都有一或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的 DOM 方法主要有三个,分别是 getAttribute() 、 setAttribute() 和 removeAttribute() 。
var div = document.getElementById("myDiv"); alert(div.getAttribute("id")); //"myDiv" alert(div.getAttribute("class")); //"bd" alert(div.getAttribute("title")); //"Body text" alert(div.getAttribute("lang")); //"en" alert(div.getAttribute("dir")); //"ltr" div.setAttribute("id", "someOtherId"); div.setAttribute("class", "ft"); div.setAttribute("title", "Some other text"); div.setAttribute("lang","fr"); div.setAttribute("dir", "rtl");-
- 创建元素
使用 document.createElement() 方法可以创建新元素。
var div = document.createElement("div"); div.id = "myNewDiv"; div.className = "box"; document.body.appendChild(div); -
-
10.1.4 Text 类型
文本节点由 Text 类型表示,包含的是可以照字面解释的纯文本内容。
-
- 创建文本节点
可以使用 document.createTextNode() 创建新文本节点,这个方法接受一个参数——要插入节点 中的文本。
var element = document.createElement("div"); element.className = "message"; var textNode = document.createTextNode("Hello world!"); element.appendChild(textNode); document.body.appendChild(element); -
-
10.1.5 Comment 类型
注释在 DOM 中是通过 Comment 类型来表示的。
var div = document.getElementById("myDiv"); var comment = div.firstChild; alert(comment.data); //"A comment" -
10.1.6 CDATASection 类型
CDATASection 类型只针对基于 XML 的文档,表示的是 CDATA 区域。CDATA 区域只会出现在 XML 文档中,因此多数浏览器都会把 CDATA 区域错误地解析为 Comment或 Element 。
<div id="myDiv"><![CDATA[This is some content.]]></div> -
10.1.7 DocumentType 类型
DocumentType 类型在 Web 浏览器中并不常用,仅有 Firefox、Safari 和 Opera 支持它。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> -
10.1.8 DocumentFragment 类型
在所有节点类型中,只有 DocumentFragment 在文档中没有对应的标记。DOM 规定文档片段 (document fragment)是一种“轻量级”的文档,可以包含和控制节点,但不会像完整的文档那样占用 额外的资源。
var fragment = document.createDocumentFragment(); var ul = document.getElementById("myList"); var li = null; for (var i=0; i < 3; i++){ li = document.createElement("li"); li.appendChild(document.createTextNode("Item " + (i+1))); fragment.appendChild(li); } ul.appendChild(fragment); -
10.1.9 Attr 类型
元素的特性在 DOM 中以 Attr 类型来表示。
var attr = document.createAttribute("align"); attr.value = "left"; element.setAttributeNode(attr); alert(element.attributes["align"].value); //"left" alert(element.getAttributeNode("align").value); //"left" alert(element.getAttribute("align")); //"left"
10.2 DOM 操作技术
- 10.2.1 动态脚本 使用 <script> 元素可以向页面中插入 JavaScript 代码,一种方式是通过其 src 特性包含外部文件, 另一种方式就是用这个元素本身来包含代码。
<script type="text/javascript" src="client.js"></script>
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
document.body.appendChild(script);
-
10.2.2 动态样式
动态样式是指在页面刚加载时不存在的样式;动态样式是在页面加载完成后动态添加到页面中的。
<link rel="stylesheet" type="text/css" href="styles.css"> var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.href = "style.css"; var head = document.getElementsByTagName("head")[0]; head.appendChild(link); -
10.2.3 操作表格
<table> 元素是 HTML 中最复杂的结构之一。
- 为了方便构建表格,HTML DOM 还为 <table> 、 <tbody>和 <tr> 元素添加了一些属性和方法。
- rows :是一个表格中所有行的 HTMLCollection 。
- cells :保存着 元素中单元格的 HTMLCollection 。
- 为了方便构建表格,HTML DOM 还为 <table> 、 <tbody>和 <tr> 元素添加了一些属性和方法。
-
10.2.4 使用 NodeList
var divs = document.getElementsByTagName("div"),
i,div;
for (i=0; i < divs.length; i++){
div = document.createElement("div");
document.body.appendChild(div);
}
10.3 小结
DOM 是语言中立的 API,用于访问和操作 HTML 和 XML 文档。DOM1 级将 HTML 和 XML 文档 形象地看作一个层次化的节点树,可以使用 JavaScript 来操作这个节点树,进而改变底层文档的外观和 结构。
DOM 由各种节点构成,简要总结如下。
最基本的节点类型是 Node ,用于抽象地表示文档中一个独立的部分;所有其他类型都继承自 Node 。
Document 类型表示整个文档,是一组分层节点的根节点。在 JavaScript 中, document 对象是 Document 的一个实例。使用 document 对象,有很多种方式可以查询和取得节点。
Element 节点表示文档中的所有 HTML 或 XML 元素,可以用来操作这些元素的内容和特性。
另外还有一些节点类型,分别表示文本内容、注释、文档类型、CDATA 区域和文档片段。
访问 DOM 的操作在多数情况下都很直观,不过在处理 <script> 和 <style> 元素时还是存在一些 复杂性。由于这两个元素分别包含脚本和样式信息,因此浏览器通常会将它们与其他元素区别对待。这 些区别导致了在针对这些元素使用 innerHTML 时,以及在创建新元素时的一些问题。
理解 DOM 的关键,就是理解 DOM 对性能的影响。DOM 操作往往是 JavaScript程序中开销最大的 部分,而因访问 NodeList 导致的问题为最多。 NodeList 对象都是“动态的”,这就意味着每次访问 NodeList 对象,都会运行一次查询。有鉴于此,最好的办法就是尽量减少 DOM 操作。