這篇文章主要介紹了你所不了解的javascript操作DOM的細節知識點的相關資料,需要的朋友可以參考下
一:Node類型
DOM1級定義了一個Node接口,該接口是由DOM中的所有節點類型實現。每個節點都有一個nodeType屬性,用於表明節點的類型,節點類型在Node類型中有以下幾種:
Node.ELEMENT_NODE(1); 元素節點
Node.ATTRIBUTE_NODE(2); 屬性節點
Node.TEXT_NODE(3); 文本節點
Node.DOCUMENT_NODE(9); 文檔節點
其實還有很多種,但是那些都不是很常用,所以就來理解這其中4種就可以了,我們先來看看節點類型,比如如下代碼:
HTML代碼如下:
?
1 2 3 4 5 <div id="test"> <p>aaaaaa</p> <p>bbbbbb</p> <p>cccccc</p> </div>JS如下:
?
1 2 3 4 var test = document.getElementById("test"); if(test.nodeType === Node.ELEMENT_NODE) { alert(1) }如上代碼在IE8及以下下是不行的,會報錯,如下:
因為IE沒有公開Node類型的構造函數,因此在IE8-下會有錯誤,但是我們可以通過數值來比較,比如上面的要比較元素節點的話,我們可以使用1來比較,同理屬性節點是2,文本節點是3;如下代碼:
?
1 2 3 4 5 var test = document.getElementById("test"); // 下面的所有的浏覽器都支持 if(test.nodeType == 1) { alert(1) }理解nodeName與nodeValue
nodeName保存的是元素的標簽名,而nodeValue一般都是null;我們可以看如下代碼,沒有特殊的說明,HTML代碼都是上面的,因此這邊就不貼代碼了;如下JS代碼測試:
?
1 2 3 4 5 var test = document.getElementById("test"); if(test.nodeType == 1) { console.log(test.nodeName); // 打印DIV console.log(test.nodeValue); // 打印null }理解節點關系
?
1 2 3 4 5 6 7 8 9 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> </body> </html>如上代碼,我們可以把head和body是html的子元素,同理html是他們的父級元素,那麼head和body就是兄弟元素了,那麼head及body裡面的就是子元素了,我們需要明白的是每個節點都有一個childNodes屬性,其保存的是類似數組的元素,其也有length屬性,但是他不是數組Array的實例,比如我們可以看看如下測試代碼即可:
?
1 2 3 4 5 <div id="test"> <p>aaaaaa</p> <p>bbbbbb</p> <p>cccccc</p> </div>JS代碼如下:
?
1 2 3 4 5 var test = document.getElementById("test"); if(test.nodeType == 1) { console.log(test.childNodes); console.log(test.childNodes.length); }如上代碼,在標准浏覽器下及IE9+下 第一行打印如下:
[text, p, text, p, text, p, text, item: function]
第二行打印7 長度為7,因為他們把文本節點那個空格也包括進去了,但是在IE8及以下,長度為3,他們不包括文本空格的節點,因此想要統一的話,我們可以編寫HTML代碼去掉空格,如下HTML代碼即可;
aaaaaa
bbbbbb
cccccc
這個問題稍後在仔細考慮,我們現在來看看如何取得子元素,我們可以使用2種方法,第一種是使用中括號[index]索引,第二種是使用item[index]索引,如下代碼:
console.log(test.childNodes[1]); //
bbbbbb
console.log(test.childNodes.item(1)); //
bbbbbb
但是他們並不是數組,我們可以測試下代碼即可,如下代碼:
console.log(Object.prototype.toString.call(test.childNodes) === "[object Array]");
// false但是我們使其轉換為數組,如下代碼:
//在IE8 及之前版本中無效
var arrayOfNodes = Array.prototype.slice.call(test.childNodes,0);
console.log(arrayOfNodes instanceof Array);
// true不過在IE8及之前不生效;由於IE8及更早版本將NodeList實現為一個COM對象,而我們不能像使用JScript對象那樣使用對象,要想在IE低版本中轉換為Array的形式,我們可以像下面一樣封裝一個方法即可;
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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; } var test = document.getElementById("test"); var testArray = convertToArray(test.childNodes); console.log(testArray instanceof Array); // true理解parentNode(父節點),previousSibling(上一個兄弟節點),nextSibling(下一個兄弟節點);
每個節點都有一個parentNode屬性,該屬性指向文檔中父節點,previousSibling是指當前節點的上一個同胞節點,nextSibling是指當前節點的下一個同胞節點,比如如下代碼:
?
1 2 3 4 5 6 7 8 <div id="test"><p>aaaaaa</p><p>bbbbbb</p><p>cccccc</p></div> var test = document.getElementById("test"); if(test.nodeType == 1) { var secodeChild = test.childNodes[1]; console.log(secodeChild); // <p>bbbbbb</p> console.log(secodeChild.previousSibling); // <p>aaaaaa</p> console.log(secodeChild.nextSibling); // <p>cccccc</p> }如果該節點列表中只有一個節點的話,那麼該節點的previousSibling和nextSibling都為null;父節點的firstChild指向了父節點中第一個節點;如下代碼: