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