【javascript】DOM—節(jié)點層次—Node類型

節(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é)點。
好好學習
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容