javascript快速入門15--節點

水之原發表於2013-12-01

節點型別

DOM定義了Node的介面以及許多種節點型別來表示節點的多個方面!

  • Document——最頂層的節點,所有的其他節點都是附屬於它的。
  • DocumentType——DTD引用(使用<!DOCTYPE >語法)的物件表現形式,例如<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >。它不能包含子節點。
  • DocumentFragment——可以像Document一樣來儲存其他節點。
  • Element——表示起始標籤和結束標籤之間的內容,例如<tag ></tag >或者<tag / >。這是唯一可以同時包含特性和子節點的節點型別。
  • Attr——代表一對特性名和特性值。這個節點型別不能包含子節點。
  • Text——代表XML文件中的在起始標籤和結束標籤之間,或者CData Section內包含的普通文字。這個節點型別不能包含子節點。
  • CDataSection——<![CDATA[ ]]>的物件表現形式。這個節點型別僅能包含文字節點Text作為子節點。
  • Entity——表示在DTD中的一個實體定義,例如<!ENTITY foo "foo">。這個節點型別不能包含子節點。
  • EntityReference——代表一個實體引用,例如&quot;。這個節點型別不能包含子節點。
  • ProcessingInstruction——代表一個PI(處理指令)。這個節點型別不能包含子節點。
  • Comment——代表註釋。這個節點型別不能包含子節點。
  • Notation——代表在DTD中定義的記號。這個很少用到,所以我們不會討論。

還定義了對應不同節點型別的12個常量.

  • Node.ELEMENT_NODE (1)
  • Node.ATTRIBUTE_NODE (2)
  • Node.TEXT_NODE (3)
  • Node.CDATA_SECTION_NODE (4)
  • Node.ENTITY_REFERENCE_NODE (5)
  • Node.ENTITY_NODE (6)
  • Node.PROCESSING_INSTRUCTION_NODE (7)
  • Node.COMMENT_NODE (8)
  • Node.DOCUMENT_NODE (9)
  • Node.DOCUMENT_TYPE_NODE (10)
  • Node.DOCUMENT_FRAGMENT_NODE (11)
  • Node.NOTATION_NODE (12)

節點型別常量都是Node物件的屬性,但是IE不支援Node物件,但是仍可以使用數值

Node介面也定義了一些所有節點型別都包含的特性和方法。我們在下面的表格中列出了這些特性和方法:

特性/方法 型別/返回型別 說 明
nodeName String 節點的名字;根據節點的型別而定義,元素節點返回tagName,文字節點返回#text,屬性節點返回屬性名
nodeValue String 節點的值;根據節點的型別而定義.元素節點此屬性為空,文字節點些屬性即為節點中的字串,屬性節點返回屬性值
nodeType Number 節點的型別常量值之一
ownerDocument Document 指向這個節點所屬的文件
firstChild Node 指向在childNodes列表中的第一個節點
lastChild Node 指向在childNodes列表中的最後一個節點
childNodes NodeList 所有子節點的列表
previousSibling Node 指向前一個兄弟節點;如果這個節點就是第一個兄弟節點,那麼該值為null
nextSibling Node 指向後一個兄弟節點;如果這個節點就是最後一個兄弟節點,那麼該值為null
hasChildNodes() Boolean 當childNodes包含一個或多個節點時,返回真
attributes NamedNodeMap 包含了代表一個元素的特性的Attr物件;僅用於Element節點
appendChild(node) Node node新增到childNodes的末尾
removeChild(node) Node 從childNodes中刪除node
replaceChild (newnode,oldnode) Node 將childNodes中的oldnode替換成newnode
insertBefore (newnode,refnode) Node 在childNodes中的refnode之前插入newnode

除節點外,DOM還定義了一些助手物件,它們可以和節點一起使用,但不是DOM文件必有的部分。

  • NodeList——節點陣列,按照數值進行索引;用來表示一個元素的子節點。比如childNodes。NodeList有個length屬性表示節點數量
  • NamedNodeMap——同時用數值和名字進行索引的節點表;用於表示元素特性。比如元素的attributes。NamedNodeMap物件也有一個length屬性來指示它所包含的節點的數量。

這些助手物件為處理DOM文件提供附加的訪問和遍歷方法。

屬性節點

正如前面提到的,即便Node介面已具有attributes方法,且已被所有型別的節點繼承,然而,只有Element節點才能有特性。Element節點的attributes屬性其實是NamedNodeMap,它提供一些用於訪問和處理其內容的方法:

  • getNamedItem(name)——返回nodeName屬性值等於name的節點;
  • removeNamedItem(name)——刪除nodeName屬性值等於name的節點;
  • setNamedItem(node)——將node新增到列表中,按其nodeName屬性進行索引;
  • item(pos)——像NodeList一樣,返回在位置pos的節點;

請記住這些方法都是返回一個Attr節點,而非特性值。

當NamedNodeMap用於表示特性時,其中每個節點都是Attr節點,它的nodeName屬性被設定為特性名稱,而nodeValue屬性被設定為特性的值。示例:

    <p id="p1" style="background-color:red;" title="P!!!">Some Text!</p>
    var p1 = document.getElementById("p1");
    //訪問ID屬性
    alert(p1.attributes.getNamedItem("id")).nodeValue;
    //也可以用數值來訪問ID屬性
    alert(p1.attributes.item(0)).nodeValue;
    //也可以改變它的值
    p1.attributes.getNamedItem("id").nodeValue = "newP1";

 

Attr節點也有一個完全等同於(同時也完全同步於)nodeValue屬性的value屬性,並且有name屬性和nodeName屬性保持同步。我們可以隨意使用這些屬性來修改或變更特性。但這些方法都比較複雜,所以DOM又定義了三個元素方法來幫助訪問特性:

  • getAttribute(name)——等於attributes.getNamedItem(name).value
  • setAttribute(name, newValue)——等於attribute.getNamedItem(name).value = newValue
  • removeAttribute(name)——等於attributes.removeNamedItem(name)

NodeList

事實上我們早接觸過NodeList了

    var allTags = document.getElementsByTagName("*");
    alert(allTags.item(1).tagName);//訪問了第二個元素
    alert(allTags[0]);//在JavaScript可以這樣訪問第一個元素,但這隻能是JavaScript里正常執行

 

getElementsByTagName與getElementsByName都返回NodeList,可以使用item(index)方法訪問其中的內容,在JavaScript中還可使用陣列形式的下標訪問!

建立和操縱節點

迄今為止,已經學過了如何訪問文件中的不同節點,不過這僅僅是使用DOM所能實現的功能中的很小一部分。還能新增、刪除、替換(或者其他操作)DOM文件中的節點。正是這些功能使得DOM具有真正意義上的動態性。

建立新節點

DOM Document(文件)中有一些方法用於建立不同型別的節點,即便在所有的瀏覽器中的瀏覽器document物件並不需要全部支援所有的方法。下面的表格列出了包含在DOM Level 1中的方法,並列出不同的瀏覽器是否支援項。

方 法 描 述 IE MOZ OP SAF
createAttribute (name) 用給定名稱name建立特性節點 × × ×
createCDATASection (text) 用包含文字text的文字子節點建立一個CDATA Section ×
createComment(text) 建立包含文字text的註釋節點 × × × ×
createDocumentFragment() 建立文件碎片節點 × × × ×
createElement (tagname) 建立標籤名為tagname的元素 × × × ×
createEntity Reference(name) 建立給定名稱的實體引用節點 ×
createProcessing Instruction(target, data) 建立包含給定targetdata的PI節點 ×
createTextNode(text) 建立包含文字text的文字節點 × × × ×

注:IE = Windows的IE 6;MOZ = 任意平臺的Mozilla 1.5;OP=任意平臺的Opera 7.5;SAF=MacOS的Safari 1.2

最常用到的幾個方法是:createDocumentFragment()、createElement()和createText- Node();其他的一些方法要麼就是沒什麼用(createComment()),要麼就是瀏覽器的支援不夠,目前還不太能用。

動態建立一個段落示例

    var p = document.createElement("p");//建立一個元素節點,傳入標籤名
    var txt = document.createTextNode("建立文字節點,傳引數即是文字內容");
    p.appendChild(txt);//將txt所引用的文字節點插入p到p的最後面(在這裡p是空的)
    //直到現在,頁面不會出現任何內容,必須將建立的節點插入到文件中
    document.body.appendChild(p);//p將出現在最後

 

移動,刪除節點方法及注意事項——appendChild,removeChild,replaceChild,insertBefore

    var p1 = document.getElementById("p1");
    document.body.appendChild(p1);//p1將會被作為body的最後一個子節點,然而頁面上仍只有一個p
    p1.parentNode.removeChild(p1);//removeChild必須是要刪除的節點的父節點呼叫
    //p1將會從頁面上消失,然而它並沒有完全消失,我們還可以再將其插入文件
    document.body.appendChild(p1);//因為變數p1包含了節點的引用
    var p2 = document.getElementById("p2");
    p2.parentNode.replaceChild(p1,p2);//p2將會被替換成p1,p2將消失
    //而p1將從原來的位置移到p2的位置

 

克隆節點——cloneNode

基於上面的原因,DOM為我們提供了一個克隆節點的方法用於生成一個節點的副本

    var p1 = document.getElementById("p1");
    var p2 = p1.cloneNode();
    document.body.appendChild(p2);//頁面上將會多出一個段落,不過段落中什麼都沒有
    p2 = p1.cloneNode(true);//使用引數true表示克隆節點時包含子節點
    document.body.appendChild(p2);

 

相關文章