DOM的核心: Node

weixin_34292959發表於2019-01-12

 DOM的核心: Node
由於DOM是樹形結構,所以一個節點被抽象為物件Node,這是DOM的核心物件:
Node的種類一共有12種,通過Node.nodeType的取值來確定(為1-12),分為:

Js程式碼
  1. Node.ELEMENT_NODE (1)   
  2. Node.ATTRIBUTE_NODE (2)   
  3. Node.TEXT_NODE (3) //<![CDATA[ ]]>中括著的純文字,它沒有子節點   
  4. Node.CDATA_SECTION_NODE (4) //子節點一定為TextNode   
  5. Node.ENTITY_REFERENCE_NODE (5)    
  6. Node.ENTITY_NODE (6) //DTD中的實體定義<!ENTITY foo “foo”>,無子節點   
  7. Node.PROCESSING_INSTRUCTION_NODE (7) //PI,無子節點   
  8. Node.COMMENT_NODE (8)   
  9. Node.DOCUMENT_NODE (9) //最外層的Root element,包括所有其它節點   
  10. Node.DOCUMENT_TYPE_NODE (10) //DTD,<!DOCTYPE………..>   
  11. Node.DOCUMENT_FRAGMENT_NODE (11)   
  12. Node.NOTATION_NODE (12) //DTD中的Nation定義   
Node.ELEMENT_NODE (1)
Node.ATTRIBUTE_NODE (2)
Node.TEXT_NODE (3) //<![CDATA[ ]]>中括著的純文字,它沒有子節點
Node.CDATA_SECTION_NODE (4) //子節點一定為TextNode
Node.ENTITY_REFERENCE_NODE (5)
Node.ENTITY_NODE (6) //DTD中的實體定義<!ENTITY foo “foo”>,無子節點
Node.PROCESSING_INSTRUCTION_NODE (7) //PI,無子節點
Node.COMMENT_NODE (8)
Node.DOCUMENT_NODE (9) //最外層的Root element,包括所有其它節點
Node.DOCUMENT_TYPE_NODE (10) //DTD,<!DOCTYPE………..>
Node.DOCUMENT_FRAGMENT_NODE (11)
Node.NOTATION_NODE (12) //DTD中的Nation定義 

❑ Node介面包含的特性/方法
節點的屬性
nodeName 屬性將返回一個字串,其內容是給定節點的名字。如果節點是元素節點,返回這個元素的名稱;如果是屬性節點,返回這個屬性的名稱;如果是文字節點,返回一個內容為#text 的字串;

nodeType 屬性將返回一個整數,這個數值代表給定節點的型別
nodeValue 屬性將返回給定節點的當前值.如果節點是元素節點,返回null;如果是屬性節點,返回這個屬性的名稱;如果是文字節點,返回文字節點的內容;

ownerDocument 指向這個節點所屬的文件
attributes 包哈勒代表一個元素的特性的Attr物件;僅用於Element節點

childNodes 所有子節點的列表
firstChild 指向在childNodes列表中的第一個節點
lastChild 指向在childNodes列表中的最後一個節點
nextSibling 指向後一個兄弟節點;如果這個節點就是最後一個兄弟節點,那麼該值為null
previousSibling 指向前一個兄弟節點;如果這個節點就是第一個兄弟節點,那麼該值為null
parentNode 返回一個給定節點的父節點

❑ hasChildNodes() 當childNodes包含一個或多個節點時,返回真
❑ appendChild(node) 將node新增到childNodes的末尾
❑ removeChild(node) 將node從childNodes中刪除

❑ insertBefore(newnode refnode) 在childNodes中的refnode之前插入newnode

Js程式碼
  1. var container = document.getElementById("content");   
  2. var message = document.getElementById("fineprint");   
  3. var para = document.createElement("p");   
  4. container.insertBefore(para,message);  
var container = document.getElementById("content");
var message = document.getElementById("fineprint");
var para = document.createElement("p");
container.insertBefore(para,message);

  ❑ replaceChild(newnode,oldnode)將childNodes中的oldnode替換成newnode

Js程式碼
  1. var container = document.getElementById("content");   
  2. var message = document.getElementById("fineprint");   
  3. var para = document.createElement("p");   
  4. container.replaceChild(para,message);  
var container = document.getElementById("content");
var message = document.getElementById("fineprint");
var para = document.createElement("p");
container.replaceChild(para,message);

 ❑ 獲得Node:

Js程式碼
  1. /* 通過document物件 */  
  2. var oHtml = document.documentElement;   
  3.   
  4.   
  5. /* 得到<head />和<body /> */  
  6. var oHead = oHtml.firstChild;   
  7. var oBody = oHtml.lastChild;   
  8. /* 可以用這種方式 */  
  9. var oHead = oHtml.childNodes[0];   
  10. var oBody = oHtml.childNodes[1];   
  11. /* 也可以使用方法獲取陣列的索引值 */  
  12. var oHead = oHtml.childNodes.item(0);   
  13. var oBody = oHtml.childNodes.item(1);   
  14. /* 使用document.body來得到<body /> */  
  15. var oBody = document.body;  
/* 通過document物件 */
var oHtml = document.documentElement;
/* 得到<head />和<body /> */
var oHead = oHtml.firstChild;
var oBody = oHtml.lastChild;
/* 可以用這種方式 */
var oHead = oHtml.childNodes[0];
var oBody = oHtml.childNodes[1];
/* 也可以使用方法獲取陣列的索引值 */
var oHead = oHtml.childNodes.item(0);
var oBody = oHtml.childNodes.item(1);
/* 使用document.body來得到<body /> */
var oBody = document.body;

❑ createElement(element)
建立一個指定標籤名建立一個新的元素節點,返回值為指向新建元素節點的引用指標。
eg) var para = document.createElement("p");
document.body.appendChild(para);

❑ createTextNode()
建立一個包含著給定文字的新文字節點,返回一個指向新建文字節點的引用指標:
reference = document.createTextNode()
引數為新建文字節點所包含的文字字串

Js程式碼
  1. var message = document.createTextNode("hello world");   
  2. var container = document.createElement("p");   
  3. container.appendChild(message);   
  4. document.body.appendChild(container);  
var message = document.createTextNode("hello world");
var container = document.createElement("p");
container.appendChild(message);
document.body.appendChild(container);

 ❑ cloneNode()
reference = node.cloneNode(deep)
為給定節點建立一個副本,引數為 true 或者 false,true 表示同時複製該節點的子節點,false 則不復制任何子節點。

Js程式碼
  1. var para = document.createElement("p");   
  2. var message = document.createTextNode("hello world");   
  3. para.appendChild(message);   
  4. document.body.appendChild(para);   
  5. var newpara = para.cloneNode(true);   
  6. document.body.appendChild(newpara);  
var para = document.createElement("p");
var message = document.createTextNode("hello world");
para.appendChild(message);
document.body.appendChild(para);
var newpara = para.cloneNode(true);
document.body.appendChild(newpara);


❑ 檢測節點型別
通過使用nodeType特性檢驗節點型別:
alert(document.nodeType); //outputs "9"
alert(document.documentElement.nodeType); //outputs "1"
這個例子中,document.nodeType返回9,等於Node.DOCUMENT_NODE;同時document. documentElement.nodeType返回1,等於Node.ELEMENT_NODE。

也可以用Node常量來匹配這些值:
alert(document.nodeType == Node.DOCUMENT_NODE); //true
alert(document.documentElement.nodeType == Node.ELEMENT_NODE); //true

這段程式碼可以在Mozilla 1.0+、Opera 7.0+和Safari 1.0+上正常執行。但是IE不支援這些常量,所以這些程式碼在IE上會產生錯誤。


❑ 處理特性
即便Node介面已具有attributes方法,且已被所有型別的節點繼承,然而,只有Element節點才能有特性。
Element節點的attributes屬性其實是NamedNodeMap,它提供一些用於訪問和處理其內容的方法:
getNamedItem(name) 返回nodeName屬性值等於name的節點;
removeNamedItem(name) 刪除nodeName屬性值等於name的節點;
setNamedItem(node) 將node新增到列表中,按其nodeName屬性進行索引;
item(pos)  像NodeList一樣,返回在位置pos的節點;

請記住這些方法都是返回一個Attr節點,而非特性值。
NamedNodeMap物件也有一個length屬性來指示它所包含的節點的數量。

當NamedNodeMap用於表示特性時,其中每個節點都是Attr節點,它的nodeName屬性被設定為特性名稱,而nodeValue屬性被設定為特性的值。
例如,假設有這樣一個元素:
<p id="p1" style="color:red">hello world!</p>

假設變數oP包含指向這個元素的一個引用。於是可以這樣訪問id特性的值:
var sId = oP.attributes.getNamedItem("id").nodeValue; //p1
或者
var sId = oP.attributes.item(0).nodeValue;

還可以通過給nodeValue屬性賦新值來改變id特性:
oP.attributes.getNamedItem("id").nodeValue = "newId";

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)

要獲取前面用的<p/>的id特性,只需這樣做:
var sId = oP.getAttribute("id");
更改ID:
oP.setAttribute("id", "newId");


❑ setAttribute()
element.setAttribute(attributeName,attributeValue);
為給定元素節點新增一個新的屬性值或是改變它的現有屬性

❑ getAttribute
attributeValue = element.getAttribute(attributeName)
返回一個給定元素的一個給定屬性節點的值。

❑ getElementById()
element = document.getElementById(ID)
尋找一個有著給定 id 屬性值的元素,返回一個元素節點

❑ getElementsByName()
用來獲取所有name特性等於指定值的元素:
elements = document.getElementsByName(tagName)
返回一個節點集合。

❑ getElementsByTagName()
用於尋找有著給定標籤名的所有元素:
elements = document.getElementsByTagName(tagName)
返回一個節點集合。

❑ 生成與操作Node
createAttribute(name) :建立一個名為name的屬性節點。
createCDATASection(text) :建立一個子節點為text的CDATA區。
createComment(text) :建立一個註釋內容為text的註釋節點。
createDocumentFragment() :建立一個文件片斷(fragment)節點。
createElement(tagName) :建立一個名為tagName的元素節點。
createEntityReference(name) :Creates an entity reference node with the given name。
createProcessingInstruction(target, data) :Creates a PI node with the given target and data。
createTextNode(text) :建立一個包含text的文字節點。
其中最重要的方法是createElement(),createDocumentFragment(), create TextNode()。

Js程式碼
  1. /*使用createElement(),createTextNode(),appendChild()動態新增節點*/  
  2. function createMessage(){   
  3.  var op = document.createElement("p");   
  4.  var oText = document.createTextNode("hello world!");   
  5.  op.appendChild(oText);   
  6.  document.body.appendChild(op);   
  7. }  
/*使用createElement(),createTextNode(),appendChild()動態新增節點*/
function createMessage(){
var op = document.createElement("p");
var oText = document.createTextNode("hello world!");
op.appendChild(oText);
document.body.appendChild(op);
}

❑ 使用createDocumentFragment()

Js程式碼
  1. //通常做法   
  2. var arrText = ['first''second''third'];   
  3. for(var i=0; i<arrText.length; i++){   
  4.     var op = document.createElement('p');   
  5.     var oText = document.createTextNode(arrText[i]);   
  6.     op.appendChild(oText);   
  7.     document.body.appendChild(op);   
  8. }   
  9.   
  10. //使用documentFragment   
  11. var arrText = ['first''second''third'];   
  12. var oFragment = document.createDocumentFragment();   
  13. for(var i=0; i<arrText.length; i++){   
  14.     var op = document.createElement('p');   
  15.     var oText = document.createTextNode(arrText[i]);   
  16.     op.appendChild(oText);   
  17.     oFragment.appendChild(op);   
  18. }   
  19. document.body.appendChild(oFragment);  
//通常做法
var arrText = ['first', 'second', 'third'];
for(var i=0; i<arrText.length; i++){
var op = document.createElement('p');
var oText = document.createTextNode(arrText[i]);
op.appendChild(oText);
document.body.appendChild(op);
}
//使用documentFragment
var arrText = ['first', 'second', 'third'];
var oFragment = document.createDocumentFragment();
for(var i=0; i<arrText.length; i++){
var op = document.createElement('p');
var oText = document.createTextNode(arrText[i]);
op.appendChild(oText);
oFragment.appendChild(op);
}
document.body.appendChild(oFragment);

  通過DocumentFragment的方式效率更高。

❑ HTML DOM:
使用DOM的核心方法是針對所有XML的,針對HTML DOM有特殊的方法,如
使用DOM core:oImg.setAttribute("src", "picture.gif");
使用HTML DOM:oImg.src = "picture.jpg";

相關文章