【EASYDOM系列教程】之遍歷節點

Node 對象提供了一系列的屬性和方法用來利用 DOM 節點樹結構中節點的關係實現遍歷其中的節點。javascript

關於節點之間的關係,能夠參考《DOM樹結構》一節有關節點之間關係的內容。html

獲取父節點

經過 HTML 頁面中指定元素查找其父級節點,咱們可使用 Node 對象的 parentNode 屬性實現:java

pNode = node.parentNode;

在上述語法結構中,parentNode 屬性返回指定節點的父節點。node

值得注意的是: 一個元素節點的父節點,多是一個元素節點,也多是一個文檔節點。瀏覽器

如下代碼示例,就是經過 parentNode 屬性獲取指定節點的父節點,再實現其餘操做的:ide

var btn = document.getElementById('btn');
var parentNode = btn.parentNode;
var className = parentNode.className;
className += ' animate';
parentNode.className = className;

獲取父元素節點

Node 對象除了提供了 parentNode 屬性能夠獲取指定節點的父節點以外,還提供了 parentElement 屬性獲取指定節點的父元素節點。學習

parentElementNode = node.parentElement;

在上述語法結構中,parentElement 屬性返回指定節點的父元素節點。ui

值得注意的是: 若是一個節點沒有父節點,或者父節點不是一個元素節點的話,parentElement 屬性返回 null。spa

如下代碼示例,就是經過 parentElement 屬性獲取指定節點的父元素節點,再實現其餘操做的:code

var btn = document.getElementById('btn');
var parentElement = btn.parentElement;
var className = parentElement.className;
className += ' animate';
parentElement.className = className;

父節點與父元素節點的區別

所謂父節點,並無指定某個節點的父節點必定是哪一個類型的節點。而父元素節點,指定了某個節點的父節點必定是元素節點。

  • parentNode: 獲取指定節點的父節點,其父節點不必定是元素節點。

  • parentElement: 獲取指定節點的父元素節點,其父節點必須是元素節點。

若是咱們獲取 <html> 元素的父節點的話,就是 document 文檔節點。而 document 文檔節點並非一個元素節點。以下述代碼示例:

// 獲取 <html> 元素
var html = document.documentElement;
console.log('parentNode: ' + html.parentNode);
console.log('parentElement: ' + html.parentElement);

上述代碼示例,輸出的結果以下:

parentNode與parentElement的區別

獲取子節點

經過 HTML 頁面中指定元素查找其子節點,咱們能夠經過如下 Node 對象的屬性實現:

屬性名 描述
childNodes 獲取指定節點的全部子節點
firstChild 獲取指定節點的第一個子節點
lastChild 獲取指定節點的最後一個子節點

值得注意的是: HTML 頁面中某個元素的子節點不必定是惟一的。

獲取全部子節點

Node 對象提供了 childNodes 屬性用於獲取 HTML 頁面中指定節點的全部子節點:

var ndList = Node.childNodes;

在上述語法結構中,childNodes 屬性的返回值 ndList 是一個 NodeList 對象,而且爲只讀。該屬性獲取一個包含指定節點的全部子節點的集合。

值得注意的是: childNodes 屬性返回的是一個動態的 NodeList 對象。有關動態 NodeList 的內容,請參考《定位頁面元素》一節的內容。

如下代碼示例,就是經過指定節點獲取其全部子節點,再實現其餘操做的:

var parentNode = document.getElementById('parent');
var children = parentNode.childNodes;
console.log(children);

上述代碼示例,輸出的結果以下:

childNodes的結果

咱們會發現,獲取到的全部子節點,除了真正的子節點 <button> 以外,還具備 4 個文本節點。

空白節點

主流瀏覽器解析 HTML 頁面內容爲 DOM 節點樹結構時,會產生空文本的空白節點。這是由 HTML 頁面源代碼中的換行引發的:

<div id="parent" class="button-group">
    <button id="btn" name="btn" class="button">A Button</button>
    <button name="btn" class="button">A Button</button>
    <button name="btn" class="button">A Button</button>
</div>

上述代碼示例的 DOM 節點樹結構以下圖所示:

空白節點問題

若是將 HTML 頁面的源代碼編寫成一行時,這個空白節點的問題能夠獲得解決。但這種解決方式妨礙了咱們代碼的可讀性,並不建議這樣解決。

值得注意的是: IE 8 及以前版本的瀏覽器中不存在空白節點問題。

空白節點的解決方案

在開發中,空白節點的問題將 DOM 節點樹結構的解析及操做增長了很多的難度和麻煩。咱們這裏提供一種比較簡單有效的解決方式:

  1. 棄用 DOM 中 Node 對象用於獲取指定節點的子節點和兄弟節點的屬性。

  2. 經過使用 getElementsByTagName() 方法實現相應功能。

好比咱們要查找 HTML 頁面指定元素的全部子節點的話,咱們按照以下代碼示例實現:

var parentNode = document.getElementById('parent');
var children = parentNode.getElementsByTagName('button');
console.log(children);

上述代碼示例運行的結果以下:

空白節點解決方案

關於 DOM 中爲何要具備空白節點以及更完整的解決方案,能夠參考 Mozilla 社區的《DOM 中的空白符》

獲取第一個子節點

Node 對象提供了 firstChild 屬性用於獲取指定節點的第一個子節點:

var first_child = node.firstChild;

在上述語法結構中,firstChild 屬性返回的 first_child 表示當前節點的第一個子節點的引用。

值得注意的是: 若是當前節點無子節點,則 firstChild 屬性返回 null。

如下代碼示例,就是經過指定節點獲取其第一個子節點,再實現其餘操做的:

var parentNode = document.getElementById('parent');
var firstChild = parentNode.firstChild;

經過上述代碼示例,咱們最終獲得依舊是空白節點,而並不是第一個子節點。

var parentNode = document.getElementById('parent');
var firstChild = parentNode.getElementsByTagName('button')[0];
console.log(firstChild);

經過 getElementsByTagName() 方法替換以後,所獲得的節點纔是真正的第一個節點。

獲取最後一個節點

Node 對象提供了 lastChild 屬性用於獲取指定節點的最後一個子節點:

var last_child = node.lastChild;

在上述語法結構中,lastChild 屬性返回的 last_child 表示當前節點的最後一個子節點的引用。

值得注意的是: 若是當前節點無子節點,則 lastChild 屬性返回 null。

如下代碼示例,就是經過指定節點獲取其最後一個子節點,再實現其餘操做的:

var parentNode = document.getElementById('parent');
var lastChild = parentNode.lastChild;

經過上述代碼示例,咱們最終獲得依舊是空白節點,而並不是最後一個子節點。

var parentNode = document.getElementById('parent');
var children = parentNode.getElementsByTagName('button');
var lastChild = children[children.length-1];

經過 getElementsByTagName() 方法替換以後,所獲得的節點纔是真正的最後一個節點。

獲取相鄰兄弟節點

經過 HTML 頁面中指定元素查找其相鄰兄弟節點,咱們能夠經過如下 Node 對象的屬性實現:

屬性名 描述
previousSibling 獲取指定節點的前面相鄰兄弟節點
nextSibling 獲取指定節點的後面相鄰兄弟節點

獲取相鄰前面兄弟節點

Node 對象提供了 previousSibling 屬性用於獲取指定節點的前面相鄰兄弟節點:

previousNode = node.previousSibling;

在上述語法結構中,previousSibling 屬性返回的 previousNode 表示當前節點的前一個兄弟節點。

值得注意的是: 若是當前節點無前一個兄弟節點,則 previousSibling 屬性返回 null。

如下代碼示例,就是經過指定節點獲取其前面相鄰兄弟節點,再實現其餘操做的:

var elem = document.getElementById('btn');
var previousSibling = elem.previousSibling;

經過上述代碼示例,咱們最終獲得依舊是空白節點,而並不是前面相鄰兄弟節點。

// 判斷獲取的兄弟節點是否爲元素節點
if ( previousSibling.nodeType != 1){
    previousSibling = previousSibling.previousSibling;
}

經過判斷獲取的節點類型是否爲元素節點,實現如何獲取真正的前面相鄰兄弟節點。

獲取相鄰後面兄弟節點

Node 對象提供了 nextSibling 屬性用於獲取指定節點的後面相鄰兄弟節點:

nextNode = node.nextSibling;

在上述語法結構中,nextSibling 屬性返回的 nextNode 表示當前節點的後一個兄弟節點。

值得注意的是: 若是當前節點無後一個兄弟節點,則 nextSibling 屬性返回 null。

如下代碼示例,就是經過指定節點獲取其後面相鄰兄弟節點,再實現其餘操做的:

var elem = document.getElementById('btn');
var nextSibling = elem.nextSibling;

經過上述代碼示例,咱們最終獲得依舊是空白節點,而並不是後面相鄰兄弟節點。

// 判斷獲取的兄弟節點是否爲元素節點
if ( nextSibling.nodeType != 1){
    nextSibling = nextSibling.nextSibling;
}

經過判斷獲取的節點類型是否爲元素節點,實現如何獲取真正的後面相鄰兄弟節點。


本教程免費開源,任何人均可以避免費學習、分享,甚至能夠進行修改。但須要註明做者及來源,而且不能用於商業。

本教程採用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。

圖片描述

相關文章
相關標籤/搜索