-
HTML DOM
-
DOM Core
- 提供HTML與XML文件瀏覽、處理和維護階層架構的功能。
-
功能
-
瀏覽(Navigator)
- 走訪各節點
-
參考(Reference)
- 存取節點
- 提供一致的走訪方式,只要建立好樹狀結構,所有能走訪到的節點就是標籤物件,
文字節點都可以使用相同的nodeValue屬性更改其內容。
-
DOM HTML
- HTML專屬的DOM API,提供現成的物件模型
- 需使用id/name屬性或forms[]、images[]等物件集合才能取得標籤物件,
而且每種標籤物件都擁有不同的屬性。
- DOM Core可使用在HTML與XML,DOM HTML則針對HTML
-
每一節點都是一個物件
- DOM HTML提供各節點物件的屬性和方法
- DOM Core提供屬性來走訪節點
- W3C DOM只能更改文字節點的內容,其它標籤物件的屬性和方法還是來自DOM HTML。
-
轉換為節點樹
-
<table>
<tbody>
<tr><td>HTML</td><td>CSS</td></tr>
<tr><td>Javascript</td><td>jQuery</td></tr>
</tbody>
</table>
-
節點圖
-
table
- tbody
- tr
- td
- HTML
- td
- CSS
- tr
- td
- Javascript
- td
- jQuery
-
樹狀結構
-
下一層的子節點
- Child Node
- tbody是table的Child Node
-
上一層的父節點
- Parent Node
- table是tbody的Parent Node
-
左右節點(兄弟)
- Sibling Node
- tr與tr或tr之下td與td,各為Sibling Node
-
最下層葉節點
- Leaf Node
- td為Leaf Node
-
文字節點(HTML的內容)
- Text Node
- HTML/CSS/Javascript/jQuery
- 在轉換一般table時需注意,要先將table轉換成HTML 4.0版的表格,即擁有<tbody>標籤,這樣在訪問時,才不會出錯。
-
<font>
-
IE
- IE在轉換時,會在<font>後多加一個文字節點#text
- 不建議使用<font>標籤,請改用CSS
-
在DOM中有3種節點
-
元素節點
- element node,各種標籤便是這些元素節點的名稱,元素節點可以包含其他元素,唯一沒有被包含只有根元素<html>
-
屬性節點
- attribute node,屬性節點總是被包含在元素節點之中,例<a href="http://kkbruce.blogspot.com">kkbruce</a>,
a是元素節點名稱,href是屬性節點名稱
-
文字節點
- text node,標籤裡具體的文字內容,網頁最終目的是向使用者展示內容
-
屬性
-
唯讀屬性
-
W3C DOM唯讀屬性
-
firstChild
- 傳回第一個子節點childNodes物件集合,包含此節點下所有的子節點
- Node
-
lastChild
- 傳回最後一個子節點的childNodes物件集合,包含此節點下所有的子節點
- Node
-
parentNode
- 傳回父節點的物件,如已是根節點,傳回null
- Node
-
nextSibling
- 傳回下一個兄弟節點物件,如已是最後一個節點,傳回null
- Node
-
previousSibling
- 傳回上一個兄弟節點物件,如已是第一個節點,傳回null
- Node
-
nodeName
- 傳回節點的HTML標籤(英文大寫)名稱
- String
-
nodeType
- 傳回節點種類,1是標籤(element node)、2是屬性(attribute node)、3為文字(text node)
- Number
-
specified
- 布林值,傳回在HTML標籤是否有設定指定的屬性值
- Boolean
-
讀寫屬性
-
W3C DOM讀寫屬性
-
nodeValue
- 存取文字節點(text node),其他種類的節點傳回null
- String
-
物件集合
- W3C DOM物件集合可以取得下一層子節點和節點的屬性
-
W3C DOM物件集合
-
attributes
- 節點屬性的物件集合,可以直接使用名稱來存取,僅用於元素節點
- NameNodeMap
-
childNodes
- 所有子節點的物件集合(Array),方法item(i)可訪問第i+1個節點
- NodeList
-
在IE中可以直接使用id/name屬性來取得指定的節點物件,但用此方法實作的程式碼相容性不佳,
建議先使用getElementById("id")來取得指定的節點物件,然後再實作以確保Browser相容性
- myid.childNodes[0].firstChild.nodeValue = "ASP.NET"
- var objValue = document.getElementById("myid");
objValue.childNodes[0].firstChild.nodeValue = "ASP.NET";
-
IE與其他Browser中childNodes走訪不同問題
- 我們在使用childNodes走訪節點時,IE會依順序走訪各元素節點,但MF不光是元素節點,連它們之間的空格也被當成子節點計算
-
範例
-
<ul id="comicList">
<li>航海王</li>
<li id="Naruto">火影忍者</li>
<li>海棉寶寶</li>
<ul>
-
var eleUL=document.getElementById("comicList");
var listName="";
if (ele.hasChildNodes()) {
var eleLI = eleUL.childNodes;
for (var i=0,len=eleLI.length;i<len;i++){
listName += eleLI[i].nodeName + "\n";
}
alert(listName);
}
- IE
- LI
LI
LI
- MF
- #text
LI
#text
LI
#text
LI
#text
-
解決
- function nextSib(node){
var tempLast = node.parentNode.lastChild; //取得node的最後一個節點
if (node ==tempLast) { //是否為最後一個節點
return null;
}
var tempObj = node.nextSibling; //非最後一個,可找下一個Node
while ( tempObj.nodeType!=1 && tempObj.nextSibling!=null) //nodeType不是元素節點且不是最後一個,即找到元素節點為止
tempObj = tempObj.nextSibling; //往下找下一個
return (tempObj.nodeType==1) ? tempObj:null; //如果是元素節點,傳回節點本身,否則傳回null
}
- function prevSib(node){
var tempFirst = node.parentNode.firstChild; //取得node的第一個節點
if (node ==tempFirst) { //是否為第一個節點
return null;
}
var tempObj = node.previousSibling; //非第一個,可往上找上一個Node
while ( tempObj.nodeType!=1 && tempObj.previousSibling!=null) //nodeType不是元素節點且不是第一個,即找到元素節點為止
tempObj = tempObj.previousSibling; //往上找上一個
return (tempObj.nodeType==1) ? tempObj:null; //如果是元素節點,傳回節點本身,否則傳回null
}
- var eleLI = document.getElementById("Naruto");
var nextItem = nextSib(eleLI);
var preItem = prevSib(eleLI);
if (nextItem != null) //傳回不是null,是元素節點
...
-
方法
- W3C DOM提供方法能建立、刪除、複製、交換、取代節點
-
W3C DOM方法
-
appendChild
- 在obj(父)節點新增子節點obj(子),傳回新增的節點物件
- obj(父).appendChild(obj(子))
-
cloneNode
- objNew = objDup.cloneNode(deep)
- 複製objDup節點的新節點物件,deep為false僅複製此節點,true連子節點的整個節點樹都複製
-
createElement
- objNew = document.createElement("tagName")
- 建立一個HTML節點物件
-
createTextNode
- objNew = document.createTextNode(string)
- 建立文字節點
-
hasChildNodes
- objNode.hasChildNodes()
- 檢查節點是否擁有子節點,有為true
-
insertBefore
- obj(父).insertBefore(obj(子),objBrother)
- 在obj(父)節點前插入一個子節點obj(子),位置在objBrother節點前
-
removeChild
- obj.parentNode.removeChild(targetNode)
- 先找到要刪除的節點,透過parentNode的removeChild()方法來刪除目標節點
-
replaceChild
- obj.parentNode.replaceChild(newNode,oldNode)
- 先找到要替換的節點,透過parentNode的replaceChild()方法來替換節點
-
getAttribute
- obj.getAttribute("attr")
- 讀取obj的attr屬性值,例obj.getAttribute("title");
-
setAttribute
- obj.setAttribute("attr","value")
- 設定obj的attr屬性的值為value,例obj.setAttribute("src","bruce.png");
-
insertAfter
- DOM只有提供insertBefore()在目標元素之前插入新元素,或是appendChild()在父元素的childNodes尾新增新元素, 如果需要在特用元素後插入新元素,需自行撰寫
- function insertAfter(newElement, targetElement){
var tParent = targetElement.parentNode;
if (tParent.lastChild == targetElement)
tParent.appendChild(newElement);
else
tParent.insertBefore(newElement, targetElement.nextSibling);
}
-
新增HTML Tag步驟
-
建立節點
- var objNew = document.createElement("P"); /* 新增HTML節點 */
var objText = document.createTextNode("新增說明文字"); /* 新增文字節點 */
-
進行處理
- objNode.appendChild(objNew); /* 將objNew節點加入objNode節點最後面 */
objNew.appendChild(objText); /* 將objText文字節點加入objNew節點之後 */
- 例如,在一個空的<table>可以一層一層加上<tr>、<td>來自由動態產生你所想要的<table>
-
objNode
- ...
-
objNew
- objText
-
改變節點文字的安全步驟
-
刪除所有子節點
- removeChild()
-
根據新內容,建立新內容節點
- createElement(), createTextNode()
-
將新內容節點,附加在目標節點之下
- appendChild()
- function replaceNodeText(id, newText){
var node=document.getElementById(id);
while (node.firstChild)
node.removeChild(node.firstChild);
node.appendChild(document.createTextNode(newText);
}
-
樣式
- DOM提供了透過節點取用樣式的途徑
-
className屬性
- 提供對節點樣式類別的存取
- alert(ele.className);
- ele.className = "highlight";
-
style屬性
- 提供對單一樣式的存取
- ele.style.visibility = "hidden";
ele.style.display = "none";