DOM(文件物件模型)是針對HTML和XML文件的一個API(應用程式介面)。他描繪了一個層次化的節點樹,允許開發人員新增、移除和修改頁面的某一部分。
10.1 節點層次
DOM將任何HTML和XML文件描繪成一個由多層節點構成的結構。
文件節點(Document)是每個文件的根節點。文件節點只有一個子節點(HTML文件中實終是<html>),我們稱之為文件元素(每個文件只能有一個文件元素)。文件元素是文件的最外層元素,其他所有元素都包含在文件元素中。
每一段標記都能通過樹中一個節點來表示,包括特性、文件型別、註釋等,共有12種節點型別。這些型別都繼承自一個基型別。
10.1.1 Node型別
JavaScript中的所有節點型別都繼承自Node型別,所有的節點型別都共享相同的基本屬性和方法。
nodeType屬性:表明節點的型別(12種)
eg:Node.ELEMENT_NODE(1); //元素節點
通過該屬性可以確定一個節點的型別,可以通過型別字面量判等,也可以通過數字值比較。
if (someNode.nodeType == Node.ELEMENT_NODE){ //在IE中無效 alert("Node is element."); } if (someNode.nodeType == 1){ //適用於任何瀏覽器 alert("Node is element."); }
1. nodeName和nodeValue屬性
可以瞭解節點的具體資訊。
對於元素節點,nodeName儲存的始終是標籤名,nodeValue的值始終是null。
2. 節點關係
- 屬性:
1 | childNodes屬性 | 儲存NodeList物件(類陣列,但不是陣列),這個物件也有length屬性。可以通過方括號,也可以通過item()方法訪問節點。可以通過Array.prototype.slice()方法將其轉換為陣列。 |
2 | parentNode屬性 | 指向父節點。 |
3 | previousSibling / nextSibling屬性 | 訪問同一列表中的其他屬性。即前一個和後一個同胞節點。 |
4 | firstChild / lastChild屬性 | 指向childNodes列表的第一個和最後一個節點。 |
- 方法:
1 | hasChildNodes() | 檢驗是否存在子節點。存在時返回true。 |
2 | ownerDocument() | 指向整個文件的文件節點。方便直接到達頂端。 |
3. 操作節點
1 | appendChild() | 向childNodes列表的末尾新增一個節點。返回新的節點。由於任何一個節點不能同時出現在多個位置上,所以當傳入的節點是父節點的子節點時,這個節點會變成最後一個子節點。 |
2 | insertBefore() |
將節點插入到childNodes列表中一個特定的位置。接收兩個引數:要插入的節點和作為參照的節點。 插入節點後,被插入節點會成為參照節點的前一個同胞節點,同時被方法返回。省略參照節點時與appendChild()執行相同的操作。 |
3 | replaceChild() | 替換節點(複製所有的關係指標)。接收兩個引數:要插入的節點和要替換的節點。被替換的節點將從文件樹中移除,但仍然在文件中,只是沒有了自己的位置(指標)。 |
4 | removeChild() | 移除節點。返回被移除的節點。同樣被移除的節點仍然在文件中。 |
PS1:使用這幾個方法必須取得父節點(使用parentNode屬性)。
PS2:不是所有型別的節點都有子節點。在不支援子節點的節點上呼叫這些方法,會丟擲錯誤。
4. 其他方法
1 | cloneNode() |
建立呼叫這個方法的節點的一個完全相同的副本。接受一個布林值引數,表示是否執行深複製(true則執行深複製)。
複製後返回的節點歸文件所有,沒有為他指定父節點。要通過其他的方法把他加入到文件中。 IE>9及其他瀏覽器會計入空白節點。 |
2 | normalize() |
處理文件樹中的文字節點。
|
10.1.2 Document型別
Document型別表示文件。
- document物件是HTMLDocument的一個例項,表示整個HTML頁面。
- document物件是window物件的一個屬性,可以作為全域性物件來訪問。
Document節點的特徵:
- nodeType的值為9;
- nodeName的值是"#document";
- nodeValue和parentNode的值為null;
- ownerDocument的值為null。
1. 文件的子節點
1 | DocumentType(最多一個) | <!DOCTYPE>標籤,可以通過document.doctype屬性來訪問他的資訊。 |
2 | Element(最多一個) |
文件元素<html>。 通過documentElement屬性或childNodes列表(在無處理指令的情況下是firstChild)訪問可快速找到html元素。 document.body屬性可以指向<body>元素(因為該元素使用頻率高,為了便於開發增添該屬性)。 |
3 | ProcessingInstruction | 表示處理指令。 |
4 | Comment | 註釋。 |
2. 文件資訊
作為HTMLDocument的例項,document物件還有一些特殊的屬性。
1 | title | <title>元素中的文字,是當前頁面的標題。 |
2 | URL | 完整的URL。 |
3 | domain |
頁面的域名。僅domain可以設定。但有一定的限制:
作用:將每個頁面的document.domain設定為相同的值,就可以互相訪問對方包含的JavaScript物件了。(解決跨域問題) |
4 | referrer | 連結到當前頁面的那個頁面的URL。在沒有來源頁面的情況下是空字串。 |
3. 查詢元素
1 | getElementById() | 引數為要取得元素的ID。找到返回該元素,沒有找到返回null。如果有多個id值相同,則只會返回第一個。 |
2 | getElementByTagName() | 引數為要取得元素的標籤名。返回元素的NodeList。在HTML文件中,返回的是HTMLCollection物件。可以通過方括號或者item()方法來訪問。 |
3 | nameItem() | HTMLCollection物件的方法。通過元素的name屬性取得集合中的項(第一項)。同時HTMLCollection物件還支援按名稱訪問項。 |
4 | getElementByName() | 返回帶有給定name屬性的所有元素(一個HTMLCollection)。 |
4. DOM的一致性檢測
ducument.implementation屬性:提供關於實現了DOM 哪些部分的資訊的物件。
他有一個方法,hasFeature()。接收兩個引數:要檢測的DOM功能的名稱和版本號。如果支援給定名稱和版本的功能,則返回true。
檢驗結果true不意味著現實與規範一致,最好除了檢測hasFeature()之外,同時使用能力檢測。
5. 文件寫入
write() / writeln():接受一個字串,即寫入輸出流中的文字。write()會原樣寫入,writeln()會在字串末尾新增一個換行符(\n)。這兩個方法可以向頁面中動態的加入內容。
//在頁面載入過程中輸出當前的日期和時間 document.write("<strong>" + (new Date()).toString() + "</strong>");
同時還可以用來動態的包含外部資源,例如JavaScript檔案等。
document.write("<script type=\"text/javascript\" src=\"file.js\"> + "<\/script>");
PS:由於不能直接包含字串"</script>"(這樣會導致該字串被解釋為指令碼的結束,後面的程式碼無法執行),所以要將這個字串分開寫。
在頁面被呈現的過程中,會直接輸出內容。如果在文件載入結束後(window.onload)再呼叫write(),那麼輸出的內容會重寫整個頁面。
方法open()和close()分別用於開啟和關閉網頁的輸出流。
10.1.3 Element型別
Element型別提供了對元素標籤名、子節點及特性的訪問。Element節點具有以下特徵:
- nodeType值為1;
- nodeName的值為元素的標籤名;
- nodeValue的值為null;
- parentNode可能是Document或Element;
tagName屬性:返回訪問元素的標籤名(與nodeName相同)。 => 在HTML中標籤名始終以全部大寫表示,需要檢驗標籤型別時最好呼叫toLowerCase()方法。
1. HTML元素
所有HTML元素都由HTMLElement型別表示。HTMLElement型別直接繼承自Element並新增了一些屬性。
- id,元素在文件中的唯一標識;
- title,有關元素的附加說明資訊,一般通過工具提示條顯示出來;
- dir,語言的方向("ltr",即left-to-right)或“rtl”;
- className,與元素的class特性對應,為元素制定的CSS類。
2. 取得特性