節(jié)點層次
- DOM 可以將任何HTML 或XML 文檔描繪成一個由多層節(jié)點構成的結構。
- 節(jié)點之間的關系構成了層次,而所有頁面標記則表現(xiàn)為一個以特定節(jié)點為根節(jié)點的樹形結構。
Node類型
- 每個節(jié)點都有一個nodeType屬性,用于表明節(jié)點的類型。節(jié)點類型由在Node類型中定義的下列的數(shù)值常量來表示。
var type = node.nodeType;
- 節(jié)點類型常量
| 常量 | 值 | 描述 |
|---|---|---|
| Node.ELEMENT_NODE | 1 | 一個 元素 節(jié)點,例如 <p> 和 <div>。 |
| Node.TEXT_NODE | 3 | Element 或者 Attr 中實際的 文字 |
| Node.PROCESSING_INSTRUCTION_NODE | 7 | 一個用于XML文檔的 ProcessingInstruction ,例如 <?xml-stylesheet ... ? > 聲明。 |
| Node.COMMENT_NODE | 8 | 一個 Comment 節(jié)點。 |
| Node.DOCUMENT_NODE | 9 | 一個 Document 節(jié)點。 |
| Node.DOCUMENT_TYPE_NODE | 10 | 描述文檔類型的 DocumentType 節(jié)點。例如 <!DOCTYPE html> 就是用于 HTML5 的。 |
| Node.DOCUMENT_FRAGMENT_NODE | 11 | 一個 DocumentFragment 節(jié)點 |
- 已棄用的節(jié)點類型常量
| 常量 | 值 | 描述 |
|---|---|---|
| Node.ATTRIBUTE_NODE | 2 | 元素 的耦合屬性 。在 DOM4 規(guī)范里Node 接口將不再實現(xiàn)這個元素屬性。 |
| Node.CDATA_SECTION_NODE | 4 | 一個 CDATASection。 在 DOM4 規(guī)范里被移除。 |
| Node.ENTITY_REFERENCE_NODE | 5 | 一個 XML 實體引用節(jié)點。 在 DOM4 規(guī)范里被移除。 |
| Node.ENTITY_NODE | 6 | 一個 XML <!ENTITY ...> 節(jié)點。 在 DOM4 規(guī)范中被移除。 |
| Node.NOTATION_NODE | 12 | 一個 XML <!NOTATION ...> 節(jié)點。 在 DOM4 規(guī)范里被移除. |
/**不同的節(jié)點類型**/
document.nodeType === Node.DOCUMENT_NODE; // true
document.doctype.nodeType === Node.DOCUMENT_TYPE_NODE; // true
var fragment = document.createDocumentFragment();
fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE; // true
var p = document.createElement("p");
p.textContent = "一點人生經(jīng)驗...";
p.nodeType === Node.ELEMENT_NODE; // true
p.firstChild.nodeType === Node.TEXT_NODE; // true
/**注釋**/
var node = document.documentElement.firstChild;
if (node.nodeType != Node.COMMENT_NODE)
console.log("滾去寫注釋!");
1、nodeName和nodeValue屬性
if (someNode.nodeType == 1){
value = someNode.nodeName; //nodeName 的值是元素的標簽名
}
2、節(jié)點關系
- 每個節(jié)點都有一個childNodes 屬性,其中保存著一個NodeList 對象。
- NodeList 對象的獨特之處在于,它實際上是基于DOM結構動態(tài)執(zhí)行查詢的結果,因此DOM結構的變化能夠自動反映在NodeList 對象中。
//如何訪問保存在NodeList 中的節(jié)點
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
- 將NodeList 對象轉(zhuǎn)換為數(shù)組
//在IE8 及之前版本中無效
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
/**由于IE8 及更早版本將NodeList實現(xiàn)為一個COM 對象,在IE 中將NodeList 轉(zhuǎn)換為數(shù)組,必須手動枚舉所有成員。**/
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;
}
- 每個節(jié)點都有一個parentNode 屬性,該屬性指向文檔樹中的父節(jié)點。
- 包含在childNodes 列表中的每個節(jié)點相互之間都是同胞節(jié)點。
- 通過使用列表中每個節(jié)點的previousSibling和nextSibling屬性,可以訪問同一列表中的其他節(jié)點。
- 列表中第一個節(jié)點的previousSibling屬性值為null,而列表中最后一個節(jié)點的nextSibling 屬性的值同樣也為null。
if (someNode.nextSibling === null){
alert("Last node in the parent’s childNodes list.");
} else if (someNode.previousSibling === null){
alert("First node in the parent’s childNodes list.");
}
- 如果列表中只有一個節(jié)點,那么該節(jié)點的nextSibling 和previousSibling 都為null。
- 所有節(jié)點都有的最后一個屬性是ownerDocument,該屬性指向表示整個文檔的文檔節(jié)點。
3、操作節(jié)點
- appendChild(),用于向childNodes 列表的末尾添加一個節(jié)點。
var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
- 如果傳入到appendChild()中的節(jié)點已經(jīng)是文檔的一部分了,那結果就是將該節(jié)點從原來的位置轉(zhuǎn)移到新位置。
//someNode 有多個子節(jié)點
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild); //false
alert(returnedNode == someNode.lastChild); //true
- insertBefore()方法,把節(jié)點放在childNodes列表中某個特定的位置上,
- 這個方法接受兩個參數(shù):要插入的節(jié)點和作為參照的節(jié)點。
- 插入節(jié)點后,被插入的節(jié)點會變成參照節(jié)點的前一個同胞節(jié)點(previousSibling),同時被方法返回。如果參照節(jié)點是null,則insertBefore()與appendChild()執(zhí)行相同的操作.
//插入后成為最后一個子節(jié)點
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
//插入后成為第一個子節(jié)點
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true
//插入到最后一個子節(jié)點前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true
- replaceChild()替換節(jié)點
- 此方法接受的兩個參數(shù)是:要插入的節(jié)點和要替換的節(jié)點。要替換的節(jié)點將由這個
方法返回并從文檔樹中被移除,同時由要插入的節(jié)點占據(jù)其位置。
//替換第一個子節(jié)點
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);
//替換最后一個子節(jié)點
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
- removeChild(),用于移除節(jié)點
//移除第一個子節(jié)點
var formerFirstChild = someNode.removeChild(someNode.firstChild);
//移除最后一個子節(jié)點
var formerLastChild = someNode.removeChild(someNode.lastChild);
- cloneNode(),用于創(chuàng)建調(diào)用這個方法的節(jié)點的一個完全相同的副本。
- 此方法接受一個布爾值參數(shù),表示是否執(zhí)行深復制。在參數(shù)為true的情況下,執(zhí)行深復制,也就是復制節(jié)點及其整個子節(jié)點樹;在參數(shù)為false的情況下,執(zhí)行淺復制,即只復制節(jié)點本身。
- 復制后返回的節(jié)點副本屬于文檔所有,但并沒有為它指定父節(jié)點。
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
var myList = document.getElementsByTagName('ul')[0];
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或7(其他瀏覽器)
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0
- normalize(),這個方法唯一的作用就是處理文檔樹中的文本節(jié)點。
- 由于解析器的實現(xiàn)或DOM操作等原因,可能會出現(xiàn)文本節(jié)點不包含文本,或者接連出現(xiàn)兩個文本節(jié)點的情況。
- 當在某個節(jié)點上調(diào)用這個方法時,就會在該節(jié)點的后代節(jié)點中查找上述兩種情況。如果找到了空文本節(jié)點,則刪除它;如果找到相鄰的文本節(jié)點,則將它們合并為一個文本節(jié)點。

好好學習