DOM(文檔對象模型)是針對HTML和XML文檔的一個API。DOM描繪了一個層次化的節點樹。容許開發人員添加、移除、修改頁面的某一部分。javascript
文檔節點是每一個文檔的根節點,文檔元素是文檔的最外層元素,文檔中其餘說有的元素都包含在文檔元素中,每一個文檔只能有一個文檔元素,在HTML 中,文檔元素始終是<html> 元素,在XML 中沒有預約義的元素,所以任何元素均可能成爲文檔元素。html
每一段標記均可以經過樹中的一個節點來表示:HTML 元素經過元素節點表示,特性(attribute)經過特性節點表示,文檔類型經過文檔類型節點表示,而註釋則經過註釋節點表示,總共有12 種節點類型。java
1.Node類型node
DOM1 級定義了一個Node 接口,該接口將由DOM中全部節點類型實現。這個Node在JavaScript中是做爲Node 類型實現的;JavaScript 中全部節點都繼承自Node 類型,所以全部節點類型都共享相同的基本屬性和方法。編程
屬性數組
每一個節點都有一個nodeType 屬性,用於代表節點的類型。節點類型由在Node類型中定義的下列 12 個數值常量來表示,任何節點類型必居其一。瀏覽器
能夠用節點的nodeType屬性和上面的常量比較,若是相等,則說明節點是 該類型的元素。因爲IE沒有公開Node類型的構造函數,因此爲了確保跨瀏覽器兼容,最好仍是將nodeType屬性與數字值進行比較。緩存
if(someNode.nodeType == 1){ //Node.ELEMENT_NODE alert("Node is an element"); }
可使用nodeName 和 nodeValue 者兩個屬性來了解節點的具體信息,對於元素節點,nodeName中保存的始終都是元素的表簽名,而nodeValue 則始終爲null。app
每個節點都保存者一個childNodes 屬性,其中保存着一個NodeList對象。NodeList是一種相似於數組的對象,用於保存一組有序的節點。NodeList 對象的獨特之處在於,它其實是基於DOM結構動態執行查詢的結果,所以DOM結構的變化可以自動反應在NodeList 對象中。dom
可使用方括號或者item方法來訪問NodeList中的對象。
var firstChild = someNode.childNodes[0]; var secondChild = someNode.childNodes.item(1); var count = someNode.childNodes.length;
可使用Array.prototype.slice()方法將NodeList轉換成普通的ArrayList對象。
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0);
每一個節點還有 prentNode、previousSibling、nextSibling、firstChild、lastChild等屬性。顧名思義,再也不一一介紹。
方法
節點的關係指針都是隻讀的,因此DOM提供了一些操做節點的方法。其中最經常使用的是appendChild(),用於向childNodes 列表的末尾添加一個節點。返回新增的節點。
使用insertBefore()方法能夠把節點方法childNodes 列表中某個特定的位置上。接收兩個參數:要插入的節點和做爲參照的節點。插入節點後,被插入的節點會變成參照節點的前一個兄弟節點(previousSibling),同時被方法返回。若是參照節點是null, 則insertBefore() 與 appendChild() 執行相同的操做。
replaceChild()方法接收兩個參數:要插入的節點和要替換的節點。要替換的節點將由這個方法返回並從文檔樹中被移除,同時由要插入的節點佔據其位置。
removeChild()方法接收一個參數,即要移除的節點。被移除的節點將成爲方法的返回值。
cloneNode() 用於建立調用這個方法的節點的一個徹底相同的副本。該方法接收一個布爾值參數,表示是否執行深複製。
2.Document類型
JavaScript 經過Document 類型表示文檔,在瀏覽器中,document 對象是HTMLDocument的一個實例,表示整個HTML頁面。並且document對象是window對象的一個屬性,所以能夠做爲全局對象來訪問。
document 的 nodeType 爲9, nodeName 爲「#document」,nodeValue 爲null parentNode 爲null,ownerDocument爲null。
Document 節點的子節點能夠是DocumentType、Element、ProcessingInstruction 或 Comment,但仍是有兩個內置的訪問其子節點的快捷方式。
第一個就是documentElement 屬性,該屬性始終指向 HTML 頁面中的<html> 元素。另外一個就是body 屬性,直接指向<body> 元素。
document 對象有一些標準的Document 對象所沒有的屬性。這些屬性提供了document 對象所表現的頁面的一些信息。
第一個屬性是 title,包含者<title> 元素中的文本----顯示在瀏覽器窗口的標題欄或標籤頁上。經過這個屬性能夠取得當前頁面的標題,也能夠修改當前頁面的標題並反應在瀏覽器的標題欄中。
URL屬性中包含頁面完整的URL,domain 屬性中包含頁面的域名,而referrer 屬性中則保存着聯街道當前頁面的哪一個頁面的URL。在沒有來源頁面的狀況下,referrer 屬性中可能會包含空字符串。全部這些信息都存在於請求的HTTP 頭部,只不過是經過這些屬性讓咱們可以在JavaScript中訪問他們而已。
document提供了兩個方法用於查找某個或某組元素的引用:getElementById() 和 getElementsByTagName()。
getElementsByTagName() 函數返回的是包含0或多個元素的 NodeList。在HTML中,這個方法會返回一個HTMLCollection 對象,做爲一個動態集合,該對象與NodeList 很是相似。
getElementsByName() 方法是HTMLDocument 特有的方法,返回帶有給定name 特性的全部元素。
document對象還有一些特殊的集合,這些集合都是HTMLCollection對象,爲訪問文檔經常使用部分提供了快捷方式。
3.Element類型
要訪問元素的標籤名,可使用nodeName屬性,也可使用tagName 屬性;這兩個屬性會返回相同的值。
全部的HTML元素都由HTMLElement 類型表示,不是直接經過這個類型也是經過它的子類型來表示。HTMLElement 類型直接繼承自Element 並添加了一些屬性。添加的這些屬性分別對應於每一個HTML都存在的下列標準特性:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>study</title> </head> <body> <div id="myDiv" class="bd" title="Body text" lang="en" dir="rtl">good morning</div> <script type="text/javascript"> var div = document.getElementById("myDiv"); alert("id=" + div.id + ", class=" + div.className + ", title=" + div.title + ", lang=" + div.title + ", dir=" + div.dir); //id=myDiv, class=bd, title=Body text, lang=Body text, dir=rtl </script> </body> </html>
getAttribute()方法也能夠取得屬性內容,也能夠取得自定義的特性。參數傳遞屬性名稱,不去分大小寫。
在經過JavaScript 以編程方式操做DOM 時,開發人員常常不使用getAttribute(),而是隻使用對象的屬性。只有在取得自定義特性值的狀況下,纔會使用getAttribute() 方法。
setAttribute() 方法能夠爲對象設置屬性,也能夠操做自定義特性,經過這個方法設置的特性名會被統一轉換成小寫形式。
removeAttribute() 方法用於完全刪除元素的特性。調用這個方法不只會清除特性的值,並且也會從元素中徹底刪除特性。
Element 類型是使用attributes 屬性的惟一一個DOM 節點類型。attributes 屬性中包含一個NamedNodeMap,是一個動態集合。元素的每個特性都是一個Attr節點表示,每一個節點都保存在NamedNodeMap對象中。NamedNodeMap對象擁有下列方法:
attributes屬性中包含一系列節點,每一個節點的nodeName 就是特性的名稱,而節點的 nodeValue 就是特性的值。要取得元素的id特性,可使用如下代碼。
var id = element.attributes.getNamedItem("id").nodeValue; var id = element.attributes["id"].nodeValue; element.attributes["id"].nodeValue = "newId";
通常來講,由於attributes 的方法不夠方便,所以開發人員更多的會使用 getAttribute()、setAttributes()、removeAttributes()方法。
建立元素,使用document.creatElement()能夠建立新元素,這個方法只接收一個參數,即要建立元素的標籤名,
var div = document.createElement("div"); div.id = "myNewDiv"; div.className = "box";
4.Text類型
能夠經過nodeValue 屬性或者 data 屬性來訪問Text 節點中包含的文本,這兩個屬性中包含的值相同。對nodeValue的修改也會經過data反映出來,反之亦然。
可使用下列方法來操做節點中的文本。
文本節點還有一個length 屬性,保存着節點中字符的數目。
建立文本節點,可使用 document.createTextNode()建立新文本節點,這個方法接受一個參數----要插入的文本。
操做表格
<table> 元素是 HTML中最複雜的結構之一,要想建立表格,通常都必須設計表示表格行、單元格、表頭等方面的標籤。因爲涉及的標籤多,所以使用核心的DOM方法建立和修改表格每每都免不了要編寫大量的代碼。爲了方便構建表格,HTML DOM 還爲<table>、<tbody>和<tr>元素添加了一些屬性和方法。
爲<table>元素添加的屬性和方法:
爲<tbody> 元素添加的屬性和方法:
爲<tr>元素添加的屬性和方法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>study</title> </head> <body> <script type="text/javascript"> var table = document.createElement("table"); table.border = 1; table.width = "100%"; //create tbody var tbody = document.createElement("tbody"); table.appendChild(tbody); //first row tbody.insertRow(0); tbody.rows[0].insertCell(0); tbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1, 1")); tbody.rows[0].insertCell(1); tbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 1, 2")); //second row tbody.insertRow(1); tbody.rows[1].insertCell(0); tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2, 1")); tbody.rows[1].insertCell(1); tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2, 2")); document.body.appendChild(table); </script> </body> </html>
NodeList
NodeList、NamedNodeMap 和 HTMLCollection 三個集合都是動態的集合,每當文檔結構發生變化是,他們都會更新。所以他們始終都會保存着最新、最準確的信息。從本質上說,全部NodeList對象都是在訪問DOM文檔時實時運行查詢。
var divs = document.getElementsByTegName("div"), i, div; for(i = 0; i < divs.length; i++){ div = document.createElement("div"); document.body.appendChild(div); }
因爲divs是動態集合,因此上面代碼會致使無限循環,解決方法是把divs.length保存到另外一個變量中進行緩存。
通常來講,應該儘可能減小訪問NodeList的次數。
DOM是語言中立的 API,用於訪問HTML 和XML 文檔。DOM1級將HTML和XML 文檔形象地看作一個層次化的節點樹,可使用JavaScript來操做這個節點樹,進而改變底層文檔的外觀和結構。