第九章 DOM
DOM(文檔對象模型)是針對HTML和XML文檔的一個API(應(yīng)用程序編程接口)慧耍。DOM描繪了一個層次化的節(jié)點樹席赂,允許開發(fā)人員添加等缀,移除和修改頁面的一部分裕循,DOM脫胎于Netscape及微軟公司創(chuàng)始的DHTML(動態(tài)HTML)臣嚣,但現(xiàn)在它已經(jīng)成為表現(xiàn)和操作頁面標(biāo)記的真正的跨平臺、語言中立的方式剥哑。
1.節(jié)點層次 :
DOM可以將任何HTML或XML文檔描繪成一個由多層次節(jié)點構(gòu)成的結(jié)構(gòu)硅则。節(jié)點分為幾種不同的類型,每種類型分別表示文檔中不同的信息或標(biāo)記株婴。每個節(jié)點都有各自的特點怎虫,數(shù)據(jù)和方法,另外節(jié)點也與其他節(jié)點存在聯(lián)系困介。節(jié)點之間構(gòu)成了層次大审,而所有頁面標(biāo)記則表現(xiàn)為一個特定節(jié)點為根節(jié)點的樹形結(jié)構(gòu)。以下面HTML為例 :
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
可以將這個簡單的HTML文檔表示為一個層次結(jié)構(gòu)座哩。如圖所示 :

文檔節(jié)點是每個文檔的根節(jié)點徒扶。在這個例子中,文檔結(jié)點只有一個子節(jié)點根穷,即 <html> 元素姜骡,我們稱之為文檔元素。文檔元素是文檔的最外層元素屿良,文檔中的其他所有元索都包含在文檔元素中圈澈。每個文檔只能有一個文檔元索。在HTML頁面中尘惧,文檔元索始終都是 <html> 元素康栈。在XML中,沒有預(yù)定義的元素喷橙,因此任何元素都可能成為文檔元索啥么。
每一段標(biāo)記都可以通過樹中的一個節(jié)點來表示HTML元索通過元素節(jié)點表示,特性(attribute) 通過特性節(jié)點表示贰逾,文檔類型通過文檔類型節(jié)點表示饥臂,而注釋則通過注釋節(jié)點表示∷契猓總共有12種節(jié)點類型,這些類型都繼承自一個基類型。
2. Node類型 :
JavaScript中所有的節(jié)點類型都繼承自 Node 類型核芽,因此所有節(jié)點類型都共享著相同的基本屬性和方法囚戚。
節(jié)點類型
每個節(jié)點都有一個 nodeType 屬性,用于表明節(jié)點的類型轧简。節(jié)點類型由在 Node 類型中定義的下列12個數(shù)值來表示驰坊,任何節(jié)點必居其一 :
- 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);
通過比較上面這些常量,可以很容易的確定節(jié)點的類型哮独,例如 :
if(someNode.nodeType == Node.ELEMENT_NODE) //在IE中無效
{
alert("Node is an element.");
}
由于IE沒有公開 Node 類型的構(gòu)造函數(shù)拳芙,因此上面的代碼在IE中會導(dǎo)致錯誤。為確逼よ担跨瀏覽器兼容舟扎,最好還是和數(shù)值進(jìn)行比較。
if(someNode.nodeType == 1) //適用于所有瀏覽器
{
alert("Node is an element.");
}
雖然 nodeType 屬性有12個可取值悴务,但是僅有3種具有使用價值:
- 元素節(jié)點 : nodeType 屬性值1睹限;
- 屬性節(jié)點 : nodeType 屬性值2;
- 文本節(jié)點 : nodeType 屬性值3讯檐;
<p title = "firstEle">Don't forget to buy this stuff.</p>
下面我們來看看那在一段 HTML 文檔里羡疗,三者的關(guān)系是怎樣的:

NodeName和nodeValue屬性
要了解節(jié)點的具體信息,可以使用 nodeName 和 nodeValue 這兩個屬性别洪。這兩個屬性的值完全取決于節(jié)點的類型叨恨。在使用這兩個值以前,最好是先檢測一下節(jié)點的類型挖垛。
if(someNode.nodeType == 1)
{
value = someNode.nodeName; //nodeName的值是元素的標(biāo)簽名
}
nodeValue : 用來得到(和設(shè)定)一個節(jié)點的值痒钝。
在實際的使用過程中,如果我們想獲得對象里的值(比如說是 p 標(biāo)簽晕换,我們給它一個 id = “description”)午乓,下面這樣做是不行的。
var des = description.nodeValue;
alert(des); //null
p 元素本身的 nodeValue 屬性是一個空值闸准,而你真正需要的是包含在 p 元素所包含的文本值益愈。包含在 p 元素里的文本是另一種節(jié)點,它是 p 元素的第一個子節(jié)點夷家。因此蒸其,你想要得到的其實是它的第一個子節(jié)點的 nodeValue 屬性值。
alert(description.childNodes[0].nodeValue);
節(jié)點關(guān)系
文檔中所有的節(jié)點之間都存在這樣或那樣的關(guān)系库快,節(jié)點間的各種關(guān)系可以用傳統(tǒng)的家族關(guān)系來描述摸袁,相當(dāng)于把文檔樹比喻成家譜。在HTML中义屏,可以將 <body> 元素看成是<html> 元素的子元素,相應(yīng)地靠汁,也就可以將 <html> 元素看成是 <body> 元素的父元素蜂大,而 <head> 元素,則可以看成是 <body> 元素
的同胞元素蝶怔,因為它們都是同一個父元素 <html> 的直接子元素奶浦。
childNodes 屬性 :
每個節(jié)點都有一個 childNodes 屬性,其中保存著一個 NodeList 對象踢星。NodeList 是一種類數(shù)組對象澳叉,用于保存一組有序的節(jié)點,可以通過位置來訪問這些節(jié)點沐悦。請注意成洗,雖然可以通過方括號語法來訪問NodeList的值,而且這個對象也有 length 屬性藏否,但它并不是 Array 的實例瓶殃。NodeList 對象的獨特之處在于,它實際上是基于DOM結(jié)構(gòu)動態(tài)執(zhí)行查詢的結(jié)果秕岛,因此DOM結(jié)構(gòu)的變化能夠自動反映在 NodeList 對象中碌燕,我們常說,NodeList 是有生命继薛、有呼吸的對象修壕,而不是在我們第一次訪問它們的某個瞬間拍攝下來的一張快照。