JavaScript DOM 總結(一)

DOM 是 Document Object Model(文檔對象模型)的縮寫。DOM 描繪了一個層次化的節點樹,允許開發人員添加、移除和修改頁面的某一部分。 HTML DOM 樹形結構如下:

這裏寫圖片描述

DOM 可以將任何 HTML 或 XML 文檔描繪成一個由多層節點構成的結構。節點分爲幾種不同的類型,每種類型分別表示文檔中不同的信息及(或)標記。每個節點都擁有各自的特點、數據和方法,另外也與其他節點存在某種關係。

Node類型屬性

DOM1 級定義了一個 Node 接口,該接口將由 DOM 中的所有節點類型實現。JavaScript 中的所有節點類型都繼承自 Node 類型,因此所有節點類型都共享着相同的基本屬性和方法。每個節點都有nodeType 、nodeName 和 nodeValue 屬性。

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)。

要了解節點的具體信息,可以使用 nodeName 和 nodeValue 這兩個屬性。這兩個屬性的值完全取決於節點的類型。例如:元素節點的 nodeName 是標籤名稱,屬性節點的 nodeName 是屬性名稱;對於文本節點,nodeValue 屬性包含文本。對於屬性節點,nodeValue 屬性包含屬性值。nodeValue 屬性對於文檔節點和元素節點是不可用的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>nodeType nodeName nodeValue屬性</title>
</head>
<body>
<div id="div1">div內文本</div>

</body>
<script type="text/javascript">

    var div = document.getElementById("div1");
    console.log(div.nodeType);  // 1
    console.log(div.nodeName);  // DIV
    console.log(div.nodeValue); // null

    var textNode = div.childNodes[0];     
    console.log(textNode.nodeType);  //3
    console.log(textNode.nodeName);  //#text
    console.log(textNode.nodeValue); //div內文本

</script>
</html>

上述代碼創建了一個div元素節點,元素節點的nodeType爲1,nodeName爲對應的節點名稱,nodeValue對元素節點不可用,因此爲null。在div內還有一段文字,爲文本節點,通過div.childNodes[0]可獲得,文本節點的nodeType爲3,nodeName永遠是 #text,nodeValue 包含文本內容。

節點關係

HTML文檔可以描述成HTML DOM樹,那麼DOM樹中的節點彼此擁有層級關係。父(parent)、子(child)和同胞(sibling)等術語用於描述這些關係。父節點擁有子節點。同級的子節點被稱爲同胞(兄弟或姐妹)。節點之間的關係可以表述如下:

這裏寫圖片描述

與節點層次關係有關的屬性

屬性 含義
parentNode 獲取該節點的父節點
childNodes 獲取該節點的子節點數組
firstChild 獲取該節點的第一個子節點
lastChild 獲取該節點的最後一個子節點
nextSibling 獲取該節點的下一個兄弟節點
previousSibling 獲取該節點的上一個兄弟節點

爲了解釋上述屬性的具體含義,下面通過具體代碼實現。首先建立HTML文檔如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM樹節點層次關係</title>
</head>
<body>
    <div id="father">
        <p id="child1">child1</p>
        <p id="child2">child2</p>
        <p id="child3">child3</p>
    </div>
</body>
</html>

1、parentNode

var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");

console.log(child1.parentNode.nodeName);  //DIV
console.log(child1.parentNode===child2.parentNode);  // true

獲取id爲child1的p元素的parentNode爲DIV,child2和child1的parentNode爲同一個。

2、childNodes

    var nodelist = father.childNodes;
    console.log(nodelist.item(1).innerHTML); // child1
    console.log(nodelist[1].innerHTML);  // child1
    console.log(nodelist.length);  // 7

上述代碼獲取div的childNodes,其中保存着一個 NodeList 對象。 NodeList 是一種類數組對象,用於保存一組有序的節點,可以通過位置來訪問這些節點。上述代碼第二行和第三行描述瞭如何獲取裏面的節點,可以通過方括號,也可以使用 item()方法。並且可以通過.length來獲取 NodeList 對象中有幾個節點。

我們注意到div中只有三個P元素,爲何通過.length得到的結果是7呢?這是因爲我們在寫HTML文檔時存在換行空格,這些換行空格表示一個文本節點,我們可以通過for循環來遍歷NodeList 對象中的每一個節點:

for (var i = 0; i < nodelist.length; i++) {
        // console.log(nodelist[i].nodeType);
        if (nodelist[i].nodeType==1) {
            console.log(nodelist[i].innerHTML);
        }else{
            console.log(nodelist[i].nodeType+":"+nodelist[i].nodeName+":("+nodelist[i].nodeValue+")");
        }
    }

在FireFox瀏覽器中得到的結果如下:

這裏寫圖片描述

3、firstChild

firstChild即獲取某個節點的第一個子節點,要獲取第一個子節點也可以通過someNode.childNodes[0]或someNode.childNodes.item(0)獲取。

4、lastChild

lastChild即獲取某個節點的最後一個子節點,要獲取最後一個子節點也可以通過someNode.childNodes [someNode.childNodes.length-1]或者someNode.childNodes.item(someNode.childNodes.length-1)

5、nextSibling

nextSibling即獲取該節點的下一個兄弟節點,同一兄弟級節點中最後一個節點的 nextSibling 屬性的值爲 null:

console.log(nodelist[0].nextSibling);  //  <p id="child1">
console.log(child1.nextSibling);  //<TextNode textContent="\n       ">
console.log(nodelist[nodelist.length-1].nextSibling);  // null

6、previousSibling

previousSibling即獲取該節點的上一個兄弟節點,同一兄弟級節點中最後一個節點的 previousSibling屬性的值同樣爲null:

console.log(nodelist[0].previousSibling); // null
console.log(child1.previousSibling); //<TextNode textContent="\n        ">
console.log(nodelist[nodelist.length-1].previousSibling); //  <p id="child3">

另外, hasChildNodes()也是一個非常有用的方法,這個方法在節點包含一或多個子節點的情況下返回 true;當然,也可以通過childNodes的length 屬性來判斷是否存在子節點。

元素節點

但是大部分情況下,我們都是需要對元素節點進行操作,對應的元素節點的屬性的如下:

屬性 含義
children 所有子元素節點
childElementCount 子元素節點個數量
firstElementChild 第一個子元素節點
lastElementChild 最後一個子元素節點
nextElementSibling 下一個兄弟元素節點
previousElementSibling 前一個兄弟元素節點

上述的六個屬性只包含元素節點,不包含文本節點,因此可以避免我們在程序中出現的換行空格被當做文本節點的情況,以下還是以上述的DOM結構來測試這六個元素節點屬性。

var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");

var childrenlist = father.children;
console.log(childrenlist.length); // 3
console.log(father.childElementCount);  // 3
console.log(childrenlist[1]);  // <p id="child2">

console.log(father.firstElementChild); // <p id="child1">

console.log(father.lastElementChild);  // <p id="child3">

console.log(child1.nextElementSibling);  //  <p id="child2">

console.log(child1.previousElementSibling);  // null

console.log(child3.nextElementSibling);  //  null

console.log(child3.previousElementSibling);  //  <p id="child2">
發佈了55 篇原創文章 · 獲贊 311 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章