前面的話
DOM可以將任何HTML描繪成一個由多層節點構成的結構。節點分為12種不同類型,每種類型分別表示文檔中不同的信息及標記。每個節點都擁有各自的特點、數據和方法,也與其他節點存在某種關系。節點之間的關系構成了層次,而所有頁面標記則表現為一個以特定節點為根節點的樹形結構。本文將詳細描述DOM間的節點關系

節點中的各種關系可以用傳統的家族關系來描述,相當于把文檔樹比喻成家譜。接下來,將把DOM節點關系分為屬性和方法兩部分進行詳細說明
屬性
父級屬性
parentNode
每個節點都有一個parentNode屬性,該屬性指向文檔樹中的父節點。對于一個節點來說,它的父節點只可能是三種類型:element節點、document節點和documentfragment節點。如果不存在,則返回null
<div id="myDiv"></div> <script> console.log(myDiv.parentNode);//body console.log(document.body.parentNode);//html console.log(document.documentElement.parentNode);//document console.log(document.parentNode);//null </script>
<div id="myDiv"></div> <script> var myDiv = document.getElementById('myDiv'); console.log(myDiv.parentNode);//body var fragment = document.createDocumentFragment(); fragment.appendChild(myDiv); console.log(myDiv.parentNode);//document-fragment </script>
parentElement
與parentNode屬性不同的是,parentElement返回的是父元素節點
<div id="myDiv"></div> <script> console.log(myDiv.parentElement);//body console.log(document.body.parentElement);//html console.log(document.documentElement.parentElement);//null console.log(document.parentElement);//null </script>
[注意]在IE瀏覽器中,只有Element元素節點才有該屬性,其他瀏覽器則是所有類型的節點都有該屬性
<div id="test">123</div> <script> //IE瀏覽器返回undefined,其他瀏覽器返回<div id="test">123</div> console.log(test.firstChild.parentElement); //所有瀏覽器都返回<body> console.log(test.parentElement); </script>
子級屬性
childNodes
childNodes是一個只讀的類數組對象NodeList對象,它保存著該節點的第一層子節點
<ul id="myUl"><li><div></div></li></ul> <script> var myUl = document.getElementById('myUl'); //結果是只包含一個li元素的類數組對象[li] console.log(myUl.childNodes); </script>
children
children是一個只讀的類數組對象HTMLCollection對象,但它保存的是該節點的第一層元素子節點
<div id="myDiv">123</div> <script> var myDiv = document.getElementById('myDiv'); //childNodes包含所有類型的節點,所以輸出[text] console.log(myDiv.childNodes); //children只包含元素節點,所以輸出[] console.log(myDiv.children); </script>
childElementCount
返回子元素節點的個數,相當于children.length
[注意]IE8-瀏覽器不支持
<ul id="myUl"> <li></li> <li></li> </ul> <script> var myUl = document.getElementById('myUl'); console.log(myUl.childNodes.length);//5,IE8-瀏覽器返回2,因為不包括空文本節點 console.log(myUl.children.length);//2 console.log(myUl.childElementCount);//2,IE8-瀏覽器返回undefined </script>
firstChild
第一個子節點
lastChild
最后一個子節點
firstElementChild
第一個元素子節點
lastElementChild
最后一個元素子節點
上面四個屬性,IE8-瀏覽器和標準瀏覽器的表現并不一致。IE8-瀏覽器不考慮空白文本節點,且不支持firstElementChild和lastElementChild
//ul標簽和li標簽之間有兩個空白文本節點,所以按照標準來說,ul的子節點包括[空白文本節點、li元素節點、空白文本節點]。但在IE8-瀏覽器中,ul的子節點只包括[li元素節點] <ul> <li></li> </ul>
<ul id="list"> <li>1</li> <li>2</li> <li>3</li> </ul> <script> console.log(list.firstChild);//標準瀏覽器中返回空白文本節點,IE8-瀏覽器中返回<li>1</li> console.log(list.lastChild);//標準瀏覽器中返回空白文本節點,IE8-瀏覽器中返回<li>3</li> console.log(list.firstElementChild);//標準瀏覽器中<li>1</li>,IE8-瀏覽器中返回undefined console.log(list.lastElementChild);//標準瀏覽器中<li>3</li>,IE8-瀏覽器中返回undefined </script>
同級屬性
nextSibling
后一個節點
previousSibling
前一個節點
nextElementSibling
后一個元素節點
previousElementSibling
前一個元素節點
與子級屬性類似,上面四個屬性,IE8-瀏覽器和標準瀏覽器的表現并不一致。IE8-瀏覽器不考慮空白文本節點,且不支持nextElementSibling和previousElementSibling
<ul> <li>1</li> <li id="myLi">2</li> <li>3</li> </ul> <script> var myLi = document.getElementById('myLi'); console.log(myLi.nextSibling);//空白節點,IE8-瀏覽器返回<li>3</li> console.log(myLi.nextElementSibling);//<li>3</li>,IE8-瀏覽器返回undefined console.log(myLi.previousSibling);//空白節點,IE8-瀏覽器返回<li>1</li> console.log(myLi.previousElementSibling);//<li>1</li>,IE8-瀏覽器返回undefined </script>
方法
包含方法
hasChildNodes()
hasChildNodes()方法在包含一個或多個子節點時返回true,比查詢childNodes列表的length屬性更簡單
<div id="myDiv">123</div> <script> var myDiv = document.getElementById('myDiv'); console.log(myDiv.childNodes.length);//1 console.log(myDiv.hasChildNodes());//true </script>
<div id="myDiv"></div> <script> var myDiv = document.getElementById('myDiv'); console.log(myDiv.childNodes.length);//0 console.log(myDiv.hasChildNodes());//false </script>
contains()
contains方法接受一個節點作為參數,返回一個布爾值,表示參數節點是否為當前節點的后代節點。參數為后代節點即可,不一定是第一層子節點
<div id="myDiv"> <ul id="myUl"> <li id="myLi"></li> <li></li> </ul> </div> <script> console.log(myDiv.contains(myLi));//true console.log(myDiv.contains(myUl));//true console.log(myDiv.contains(myDiv));//true </script>
[注意]IE和safari不支持document.contains()方法,只支持元素節點的contains()方法
//IE和safari報錯,其他瀏覽器返回true console.log(document.contains(document.body));
關系方法
compareDocumentPosition()
compareDocumentPosition方法用于確定節點間的關系,返回一個表示該關系的位掩碼
000000 0 兩個節點相同 000001 1 兩個節點不在同一個文檔(即有一個節點不在當前文檔) 000010 2 參數節點在當前節點的前面 000100 4 參數節點在當前節點的后面 001000 8 參數節點包含當前節點 010000 16 當前節點包含參數節點 100000 32 瀏覽器的私有用途
<div id="myDiv"> <ul id="myUl"> <li id="myLi1"></li> <li id="myLi2"></li> </ul> </div> <script> //20=16+4,因為myUl節點被myDiv節點包含,也位于myDiv節點的后面 console.log(myDiv.compareDocumentPosition(myUl)); //10=8+2,因為myDiv節點包含myUl節點,也位于myUl節點的前面 console.log(myUl.compareDocumentPosition(myDiv)); //0,兩個節點相同 console.log(myDiv.compareDocumentPosition(myDiv)); //4,myLi2在myLi1節點的后面 console.log(myLi1.compareDocumentPosition(myLi2)); //2,myLi1在myLi2節點的前面 console.log(myLi2.compareDocumentPosition(myLi1)); </script>
isSameNode()和isEqualNode()
這兩個方法都接受一個節點參數,并在傳入節點與引用節點相同或相等時返回true
所謂相同(same),指的是兩個節點引用的是同一個對象
所謂相等(equal),指的是兩個節點是相同的類型,具有相等的屬性(nodeName、nodeValue等等),而且它們的attributes和childNodes屬性也相等(相同位置包含相同的值)
[注意]firefox不支持isSameNode()方法,而IE8-瀏覽器兩個方法都不支持
<script> var div1 = document.createElement('div'); div1.setAttribute("title","test"); var div2 = document.createElement('div'); div2.setAttribute("title","test"); console.log(div1.isSameNode(div1));//true console.log(div1.isEqualNode(div2));//true console.log(div1.isSameNode(div2));//false </script>
文章列表