1. 程式人生 > >第10章 文檔對象模型DOM 10.1 Node節點類型

第10章 文檔對象模型DOM 10.1 Node節點類型

not 應該 特定 新增 ssi 方式 new ext prot

DOM是針對 HTML 和 XML 文檔的一個 API(應用程序編程接口) 。DOM描繪了一個層次化的節點樹,允許開發人員添加、移除和修改頁面的某一部分。DOM 脫胎於Netscape 及微軟公司創始的 DHTML (動態 HTML) , 但現在它已經成為表現和操作頁面標記的真正的跨平臺、語言中立的方式。

節點

DOM 可以將任何 HTML 或 XML 文檔描繪成一個由多層節點構成的結構。

每個節點都擁有各自的特點、數據和方法,另外也與其他節點存在某種關系。節點之間的關系構成了層次,而所有頁面標記則表現為一個以特定節點為根節點的樹形結構。

以HTML 為例:

<html>

<head>

<title>Sample Page</title>

</head>

<body>

<p>Hello World!</p>

</body>

</html>

例子中,文檔節點只有一個子節點,即 <html> 元素,我們稱之為文檔元素

文檔元素是文檔的最外層元素,文檔中的其他所有元素都包含在文檔元素中。每個文檔只能有一個文檔元素。在 HTML 頁面中,文檔元素始終都是 <html> 元素。在 XML 中,沒有預定義的元素,因此任何元素都可能成為文檔元素。

Node 類型

DOM1 級定義了一個 Node 接口,該接口將由 DOM 中的所有節點類型實現。在JavaScript 中是作為 Node 類型實現的;除了 IE 之外,在其他所有瀏覽器中都可以訪問到這個類型。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.");

}

為了確保跨瀏覽器兼容,最好還是將 nodeType 屬性與數字值進行比較,如下所示:

if (someNode.nodeType == 1){ // 適用於所有瀏覽器

alert("Node is an element.");

}

要了解節點的具體信息,可以使用 nodeName 和 nodeValue 這兩個屬性。如:

if (someNode.nodeType == 1){

value = someNode.nodeName; //nodeName 的值是元素的標簽名

}

節點之間關系。

每個節點都有一個 childNodes 屬性,其中保存著一個NodeList 對象。 NodeList 是一種類數組對象,用於保存一組有序的節點,可以通過位置來訪問這些節點。

雖然可以通過方括號語法來訪問 NodeList 的值,而且這個對象也有 length 屬性,但它並不是 Array 的實例

它實際上是基於 DOM 結構動態執行查詢的結果,因此 DOM 結構的變化能夠自動反映在 NodeList 對象中。我們常說, NodeList 是有生命、有呼吸的對象,而不是在我們第一次訪問它們的某個瞬間拍攝下來的一張快照。

可以將 NodeList 對象轉換為數組:

//在 IE8 及之前版本中無效

var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);

考慮兼容性:

function convertToArray(nodes){

var array = null;

try {

array = Array.prototype.slice.call(nodes, 0); //針對非 IE 瀏覽器

} catch (ex) {

array = new Array();

for (var i=0, len=nodes.length; i < len; i++){

array.push(nodes[i]);

}

}

return array;

}

每個節點都有一個 parentNode 屬性,該屬性指向文檔樹中的父節點。以及previousSibling

和 nextSibling 屬性,指向前一個或者後一個同級節點。

父節點的 firstChild 和 lastChild屬性分別指向其 childNodes 列表中的第一個和最後一個節點。節點不存在是均返回null。

在反映這些關系的所有屬性當中, childNodes 屬性與其他屬性相比更方便一些,因為只須使用簡單的關系指針,就可以通過它訪問文檔樹中的任何節點。另外, hasChildNodes() 也是一個非常有用的方法,這個方法在節點包含一或多個子節點的情況下返回 true ;應該說,這是比查詢 childNodes列表的 length 屬性更簡單的方法。

所有節點都有的最後一個屬性是 ownerDocument ,該屬性指向表示整個文檔的文檔節點,因此可以直接訪問文檔節點。

雖然所有節點類型都繼承自 Node ,但並不是每種節點都有子節點。

對於節點的操作

DOM 提供了一些操作節點的方法。其中,最常用的方法是appendChild() ,用於向 childNodes 列表的末尾添加一個節點。添加節點後, childNodes 的新增節點、 父節點及以前的最後一個子節點的關系指針都會相應地得到更新。 更新完成後, appendChild()返回新增的節點。

如果傳入到 appendChild() 中的節點已經是文檔的一部分了,那結果就是將該節點從原來的位置轉移到新位置。

如果需要把節點放在 childNodes 列表中某個特定的位置上,而不是放在末尾,那麽可以使insertBefore() 方法。這個方法接受兩個參數:要插入的節點和作為參照的節點。插入節點後,被插入的節點會變成參照節點的前一個同胞節點( previousSibling ) ,同時被方法返回。如果參照節點是null ,則 insertBefore() 與 appendChild() 執行相同的操作

replaceChild() 方法接受的兩個參數是: 要插入的節點和要替換的節點。 要替換的節點將由這個方法返回並從文檔樹中被移除,同時由要插入的節點占據其位置。

如果只想移除而非替換節點,可以使用 removeChild() 方法。這個方法接受一個參數,即要移除的節點。被移除的節點將成為方法的返回值

cloneNode() ,用於創建調用這個方法的節點的一個完全相同的副本。 cloneNode() 方法接受一個布爾值參數, 表示是否執行深復制。 在參數為 true的情況下,執行深復制,也就是復制節點及其整個子節點樹;在參數為 false 的情況下,執行淺復制,即只復制節點本身。

第10章 文檔對象模型DOM 10.1 Node節點類型