W3C DOM 簡介



W3C聯合各瀏覽器廠商制訂了標準物件模型,試圖讓各瀏覽器廠商遵合此一模型進行實作,以解決各瀏覽器間物件模型不一致的問題,在新的物件模型中,也對文件操作的功能加以擴充。

簡單來說,在DOM的標準下,一份文件中所有的標籤定義,包括文字,都是一個物件,這些物件以文件定義的結構,形成了一個樹狀結構。例如:
<html>
    <head>
        <title>首頁</title>
    </head>
    <body>
        <h1>Hello!World!</h1>
        <a href="Gossip/index.html">學習筆記</a>
    </body>
</html>


這份HTML文件,會形成以下樹狀的物件結構:
document                             (Document)
       |-html                        (HTMLHtmlElement)
            |-head                   (HTMLHeadElement)
            |    |-title             (HTMLTitleElement)
            |          |-首頁        (Text)
            |
            |body                    (HTMLBodyElement)
                 |-h1                (HTMLHeadingElement
                 |  |-Hello!World!   (Text)
                 |
                 |-a                 (HTMLAnchorElement)
                   |-學習筆記        (Text)

上圖右邊的括號,表示每個物件的型態(在Firefox中)。注意,document代表整個文件,而不代表html節點,你可以使用document.childNodes[0]取得html元素,childNodes表示取得子節點,取回的會是NodeList物件,是個類似陣列的物件,可使用索引值來指定取得某個子節點。方便的document.documentElement也可用來取得html元素。如果想取得body元素,也可以透過document.body來取得。注意,文字也會形成樹狀結構中的元素。

儘管你在上面看到的元素形態,有許多都帶有HTML字眼,但DOM並非專屬於HTML的物件模型,DOM API分為兩部份,一個是核心 DOM API,一個是HTML DOM API。核心API是一個獨立的規範,可以任何語言實現,可操作的對象是基於XML的任何文件,你可以在這邊找到DOM核心API的相關資料:

HTML API是核心API的延伸,專門操作HTML,各種物件對應的形態,通常會有個HTML字眼在前頭,你可以在這邊找到HTML DOM API的相關資料:

核心API文件中所有內容都視為節點,包括文件本身,再依類型區分出不同的形態:
Node
   |Document
   |Element
   |Text
   |Attr
   ...

Document代表整份文件,Element是所有標籤(也是節點)Text代表文字元素(也是節點)詳細的核心DOM類型,可以在這邊找到:
http://www.w3schools.com/xml/dom_intro.asp

Level 0 DOMwindow物件上有navigator、location、frames、screen、history等與瀏覽器相關的物件,與文件相關的物件,實際上只有document,功能也有限,這個部份納入了DOM標準,成為了DOM的子集,由於這些舊式API都是專屬於HTML,所以你在 Document 的文件上看不到相關操作,而必須在 The HTML DOM Document Object 這個專屬於HTML的DOM API上才可以找到。

同樣地,Element僅定義核心DOM API中元素的操作,而HTMLHeadElement等元素也有一些專屬HTML的API,這在 Element 中找不到,而必須在 The HTML DOM Document Object 等相關類型中尋找。

每個節點都會有nodeNamenodeType特性,前者可以取得節點的名稱,後者可以取得節點型態常數,這個常數用來查找對應的型態名稱,常數與型態名稱的對照可在這篇文件的底下找到:
http://www.w3schools.com/jsref/prop_node_nodetype.asp

舉個來說,可以搭配JavaScript,如下顯示出一個網頁的節點與型態:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript">
window.onload = function() {
var typeNames = [
'',
'[ELEMENT_NODE]',
'[ATTRIBUTE_NODE]',
'[TEXT_NODE]',
'[CDATA_SECTION_NODE]',
'[ENTITY_REFERENCE_NODE]',
'[ENTITY_NODE]',
'[PROCESSING_INSTRUCTION_NODE]',
'[COMMENT_NODE]',
'[DOCUMENT_NODE]',
'[DOCUMENT_TYPE_NODE]',
'[DOCUMENT_FRAGMENT_NODE]',
'[NOTATION_NODE]'
];

function list(parent, indent) {
var nodes = parent.childNodes;
var tree = [];
for(var i = 0; i < nodes.length; i++) {
tree.push(indent + nodes[i].nodeName +
typeNames[nodes[i].nodeType] + '<br>');
tree.push(list(nodes[i], '  ' + indent));
}
return tree.join('');
}

document.getElementById('console').innerHTML =
'document' + typeNames[document.nodeType] +
'<br>' + list(document, '  ');
};
</script>
<title>首頁</title>
</head>
<body>
<h1>Hello!World!</h1>
<a href="https://openhome.cc/Gossip/">學習筆記</a>
<div id="console"></div>
</body>
</html>

有趣的是,那些在標籤中用來換行與縮排的文字,在Firefox中亦視為文字節點,但Internet Explorer中卻不是,所以你在兩個瀏覽器中會看到不同的結果