第九章 DOM
DOM(文檔對象模型)是針對HTML和XML文檔的一個API(應用程序編程接口)。DOM描繪了一個層次化的節點樹,允許開發人員添加,移除和修改頁面的一部分,DOM脫胎于Netscape及微軟公司創始的DHTML(動態HTML),但現在它已經成為表現和操作頁面標記的真正的跨平臺、語言中立的方式。
1.節點層次 :
DOM可以將任何HTML或XML文檔描繪成一個由多層次節點構成的結構。節點分為幾種不同的類型,每種類型分別表示文檔中不同的信息或標記。每個節點都有各自的特點,數據和方法,另外節點也與其他節點存在聯系。節點之間構成了層次,而所有頁面標記則表現為一個特定節點為根節點的樹形結構。以下面HTML為例 :
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
可以將這個簡單的HTML文檔表示為一個層次結構。如圖所示 :

文檔節點是每個文檔的根節點。在這個例子中,文檔結點只有一個子節點,即 <html> 元素,我們稱之為文檔元素。文檔元素是文檔的最外層元素,文檔中的其他所有元索都包含在文檔元素中。每個文檔只能有一個文檔元索。在HTML頁面中,文檔元索始終都是 <html> 元素。在XML中,沒有預定義的元素,因此任何元素都可能成為文檔元索。
每一段標記都可以通過樹中的一個節點來表示HTML元索通過元素節點表示,特性(attribute) 通過特性節點表示,文檔類型通過文檔類型節點表示,而注釋則通過注釋節點表示。總共有12種節點類型,這些類型都繼承自一個基類型。
2. Node類型 :
JavaScript中所有的節點類型都繼承自 Node 類型,因此所有節點類型都共享著相同的基本屬性和方法。
節點類型
每個節點都有一個 nodeType 屬性,用于表明節點的類型。節點類型由在 Node 類型中定義的下列12個數值來表示,任何節點必居其一 :
- Node.ELEMENT_NODE(1);
- Node.ATTRIBUTE_NODE(2);
- Node.TEXT_NODE(3);
- Node.CDATA_SECTION_NODE(4);
- Node.ENTITY_REFERENCE_NODE(5);
- Node.ENTITY_NODE(6);
- Node.PROCESSING_INSTRUCTION_NODE(7);
- Node.COMMENT_NODE(8);
- Node.DOCUMENT_NODE(9);
- Node.DOCUMENT_TYPE_NODE(10);
- Node.DOCUMENT_FRAGMENT_NODE(11);
- Node.NOTATION_NODE(12);
通過比較上面這些常量,可以很容易的確定節點的類型,例如 :
if(someNode.nodeType == Node.ELEMENT_NODE) //在IE中無效
{
alert("Node is an element.");
}
由于IE沒有公開 Node 類型的構造函數,因此上面的代碼在IE中會導致錯誤。為確保跨瀏覽器兼容,最好還是和數值進行比較。
if(someNode.nodeType == 1) //適用于所有瀏覽器
{
alert("Node is an element.");
}
雖然 nodeType 屬性有12個可取值,但是僅有3種具有使用價值:
- 元素節點 : nodeType 屬性值1;
- 屬性節點 : nodeType 屬性值2;
- 文本節點 : nodeType 屬性值3;
<p title = "firstEle">Don't forget to buy this stuff.</p>
下面我們來看看那在一段 HTML 文檔里,三者的關系是怎樣的:

NodeName和nodeValue屬性
要了解節點的具體信息,可以使用 nodeName 和 nodeValue 這兩個屬性。這兩個屬性的值完全取決于節點的類型。在使用這兩個值以前,最好是先檢測一下節點的類型。
if(someNode.nodeType == 1)
{
value = someNode.nodeName; //nodeName的值是元素的標簽名
}
nodeValue : 用來得到(和設定)一個節點的值。
在實際的使用過程中,如果我們想獲得對象里的值(比如說是 p 標簽,我們給它一個 id = “description”),下面這樣做是不行的。
var des = description.nodeValue;
alert(des); //null
p 元素本身的 nodeValue 屬性是一個空值,而你真正需要的是包含在 p 元素所包含的文本值。包含在 p 元素里的文本是另一種節點,它是 p 元素的第一個子節點。因此,你想要得到的其實是它的第一個子節點的 nodeValue 屬性值。
alert(description.childNodes[0].nodeValue);
節點關系
文檔中所有的節點之間都存在這樣或那樣的關系,節點間的各種關系可以用傳統的家族關系來描述,相當于把文檔樹比喻成家譜。在HTML中,可以將 <body> 元素看成是<html> 元素的子元素,相應地,也就可以將 <html> 元素看成是 <body> 元素的父元素,而 <head> 元素,則可以看成是 <body> 元素
的同胞元素,因為它們都是同一個父元素 <html> 的直接子元素。
childNodes 屬性 :
每個節點都有一個 childNodes 屬性,其中保存著一個 NodeList 對象。NodeList 是一種類數組對象,用于保存一組有序的節點,可以通過位置來訪問這些節點。請注意,雖然可以通過方括號語法來訪問NodeList的值,而且這個對象也有 length 屬性,但它并不是 Array 的實例。NodeList 對象的獨特之處在于,它實際上是基于DOM結構動態執行查詢的結果,因此DOM結構的變化能夠自動反映在 NodeList 對象中,我們常說,NodeList 是有生命、有呼吸的對象,而不是在我們第一次訪問它們的某個瞬間拍攝下來的一張快照。