DOM 定義了訪問 HTML 和 XML 文檔的標準,同時它也是一個編程接口。DOM 早期針對於 XML 後來通過擴展後可用於 HTML,它把頁面映射爲一個多層節點結構,並提供方法、屬性使得程序能夠對該結構進行訪問及修改,從而改變文檔對應節點的樣式和內容。javascript
簡單來講,瀏覽器在顯示頁面的時候須要解析文檔,而腳本語言也須要獲取這份文檔,可是它們最終須要獲取到的信息是不一樣的,因此 DOM 至關於一個橋樑,溝通了腳本語言和瀏覽器。因此當咱們修改這個由 DOM 構建出的對象時,頁面也會發生相應的變化。html
若是將一個web頁面當作一個文檔,因爲不一樣的瀏覽器有各自的 DOM 標準,因此瀏覽器在解析頁面的時候會映射出不一樣的 DOM 樹模型,從而致使在操做、訪問頁面節點上存在差別。例如IE中全部的DOM對象都是以 COM 對象的形式實現的,因此和其餘瀏覽器實現的DOM對象行爲不一樣。java
注:SVG、MathML、SMIL都是基於XML的語言,它們都發布了針對了本身的 DOM 標準node
W3C 組織爲了防止 Netscape 公司和微軟按本身意願開發致使瀏覽器兼容困難狀況發生。規劃了 DOM 標準,Web 瀏覽器在 DOM 標準出現一段時間後纔開始實現它,如今的瀏覽器的首要目的就是支持 DOM,有了標準就對開發者更加的友好了。web
同時須要注意的是 DOM 不只針對 JavaScript,其餘語言也實現了DOM。編程
對象:Document、Node、ElementNode、TextNode、AttributeNode、CommentNode、NodeList跨域
接口:createElement、appendChild、setAttribute等數組
接口分類:瀏覽器
提供了全部文檔類型增刪改查操做,經過對象提供的接口修改 DOM 樹及其表明的文檔。安全
對象:Image、Table、Form、 Input 等
接口:createElement、appendChild、setAttribute等
只提供了HTML增刪改查操做,經過將 HTML 類型的封裝,來簡化和對象對應DOM的訪問和操做。
var img = new Image();
img.src = 'xxxx';
img.style.width = '100px';
複製代碼
總結:他們都爲指定的文檔類型提供了對象、屬性、方法和事件。只不過核心DOM提供的是文檔基本類型的擴展,HTML DOM提供的只是HTML類型的擴展。
DOM樹結構由一個個的節點組成,節點又分爲不一樣的類型,不一樣的類型有其特有的行爲和特徵。每一個節點都有包含着本身的信息和接口等,因爲節點和節點間有必定的關係,能夠造成了層次關係,最終的體現就是以HTML元素即文檔元素爲根節點的樹狀結構。
JavaScript 中全部的節點類型都是繼承於Node 類型,因此全部的節點都共享着相同的基本屬性和基本方法。
因爲關係指針都是可讀的,因此 DOM 提供了操做節點的方法。操做節點的時候,節點的信息以及和其餘節點的關係也會相應進行更新。
插入節點
替換節點
移除節點
克隆節點
優化文本節點
Element類型用於表現 XML 、HTML元素,提供了對元素標籤名 (TagName)、子節點、特性的訪問。也是繼承於Node類型。同時在HTML中標籤名始終以所有大寫的形式顯示,在XML中標籤名和源代碼中相同。
if(element.tagName.toLowerCase() == 'div'){
// 這樣能夠適用 HTML 和 XML 形式。
}
複製代碼
獲取標籤名可使用 ele.tagName 或者是 ele.nodeName ,兩者返回的值都是相同的。
HTMLElement類型繼承於Element,全部的HTML元素都是由該類型或者其子類型構建。下面的標準特性就是Element特有的特性。他們均可以經過元素訪問特定屬性進行訪問或修改。
div.id = test;
div.id //test;
複製代碼
id 文檔中的惟一標識符
title 有關元素的附加說明信息,通常會經過提示條顯示出來
lang 元素內容的語言代碼,不多使用
dir 語言的方向,默認左到右 ‘ltr’ ,能夠修改成右到左 ‘rtl’ 。不多使用
className 和元素的 class 特性對應,能夠爲元素指定 CSS 類。
childNodes和children的區別
childNodes返回元素、文本甚至是註釋
children只返回元素,不返回文本。
<div id="outer">
text1
<div>1</div>
<div>2</div>
<div>3</div>
text2
</div>
複製代碼
var dom = document.getElementById('outer');
console.log(dom.children)// HTMLCollection(3)
//0: div
//1: div
//2: div
console.log(dom.childNodes)// NodeList(7)
//0: text
//1: div
//2: text
//3: div
//4: text
//5: div
//6: text
複製代碼
特性(attribute )
特性是 HTML 元素節點自帶的,瀏覽器在解析 HTML 文檔時,會將標準的特性轉換成屬性,從而使得腳本程序也能夠經過屬性來訪問到這些特性(id、title、class等)。
<div id = 'test'><div>
複製代碼
div.id //因爲標籤id 爲test,因此DOM 對象就會有 body.id="test"。
div.id = 'test1';
div.id //test1;修改屬性會致使特性修改。
複製代碼
自定義特性
除了標準的特性,還存在自定義特性,須要注意的是自定義特性須要加上 data-
的前綴。這是因爲若是咱們直接使用了非標準的特性(不加data-),之後標準更新後可能會致使衝突!
<div id = 't' data-test="666"></div>
複製代碼
let elem = getElementById('t');
elem.getAttribute('test') // 666,此時添加到DOM的特性中能夠訪問到
elem.dataset.test //test,能夠在dataset中獲取到自定義特性
elem.test //undefined,自定義特性不會添加到屬性中
複製代碼
方法
elem.hasAttribute(name)
— 檢查特性是否存在。
elem.getAttribute(name)
— 獲取這個特性值。
elem.setAttribute(name, value)
— 設置這個特性值。
elem.removeAttribute(name)
— 移除這個特性。
屬性(property )
特殊特徵
style
事件處理程序(onclick)
屬性 | 特性 | |
---|---|---|
類型 | 任何值,標準的屬性具備規範中描述的類型 | 字符串 |
名字 | 名字(name)是大小寫敏感的 | 名字(name)是大小寫不敏感的 |
在大多數狀況下,最好使用 DOM 屬性。僅當 DOM 屬性沒法知足開發需求,而且咱們真的須要特性時,才使用特性,例如:
data-
開頭,那麼咱們應該使用 dataset
。href
屬性一直是一個 完整的 URL,可是咱們想要的是「原始的」值。相似於Node節點之間的關係,只不過當前關係只包含元素沒有text節點、註釋節點等其餘節點。
在瀏覽器中document是HTMLDocument對象的一個實例,同時HTMLDocument對象是繼承自 Document 對象。 實際上docuemnt 表示的是 HTML頁面,同時它也是 window 的一個屬性,因此能夠經過全局對象來訪問。經過 document 能夠獲取到瀏覽器文檔中全部節點的數據(包括方法)、以及能夠操做文檔。
如下幾個信息都是 Document 對象沒有的,都和網頁請求有關,這些全部的信息都存在 HTTP 頭部 ,只不過經過這些屬性能夠在Javascript中訪問到它們。
document.URL:URL格式爲 <協議>://<域名>:<端口>/<路徑>
document.domain:能夠獲取到當前頁面的域名。域名的設置只能愈來愈鬆散,即限制條件愈來愈低。
可使用document.domain實現跨域,可是前提是必須是同一個基礎域名,且協議和端口都得一致。Javascript 出於對安全的考慮,因此不一樣域的頁面不能互相操做。
此時若是存在基礎域名和端口都相等的URL,url1 爲a.test.com
,url2 爲 b.test.com
, 此時若是url1中的 home.html頁面須要訪問到url2 中的about.html頁面且操做about.html頁面,此時是沒法直接操做的。若是須要操做就須要在url1 和 url2 中分別設置document.domain 爲 test.com。 此時兩個頁面同域,因此能夠互相訪問和修改。
document.referrer: 保存着連接到當前頁面的 URL,若是沒有來源頁面可能爲空。
document.tiltle:能夠獲取或者修改當前頁面的標題,頁面的標題會在修改後直接更新。
getElementById 會返回第一個 id 爲指定值的元素且區分大小寫,可是須要注意若是是在 IE8 及更低版本時,不區分大小寫。在 IE7 中調用該方法時會把第一個 name屬性爲該值或者第一個 id 爲該值的元素進行返回.
<input name="test" type="text" value="Just Test"></input>
<div id="test"></div>
//document.getElementById('test') 返回input
複製代碼
getElementsByTagName() 能夠獲取到指定節點爲該標籤的全部子節點。子節點的集合即 HTMLCollection 對象。若是須要查看到文檔中全部的元素,能夠經過getElementsByTagName(」*「); HTMLCollection 對象有一個nameItem方法,能夠返回符合當前 name 爲指定值的元素。
getElementsByClassName 方法返回文檔中全部指定類名的元素集合,做爲 NodeList 對象。同時能夠同時查找多個類
var nodeList = document.getElementsByClassName("className1 className2");
複製代碼
getElementsByName() 方法可返回帶有指定名稱的對象的集合
querySelector();返回與該模式匹配的第一個元素,可兼容到CSS2
querySelectorAll();返回與該模式匹配的全部元素,底層相似於對一組元素的快照,而不是不斷的動態查詢(損耗性能 )
document.anchors:包含文檔中全部帶那麼特性的元素。
document.forms:包含文檔中全部的元素,與document.getElementByTagName("form")的到的結果相同。
document.images:包含文檔中全部的元素,與document.getElementByTagName("img")的到的結果相同。
document.links:包含文檔中全部帶href特性的元素。
理解DOM操做的關鍵,就是理解DOM對性能的影響。DOM操做每每是 JavaScript 程序中開銷最大的部分。因爲NodeList是」動態的「,因此每次訪問它的時候都會進行一次新的查詢,最好避免的方法就是少訪問和減小 DOM 操做。
-----高程
在操做類名的時候能夠經過元素的classList屬性對類名進行添加,刪除或者替換,其實是直接操做className的語法糖,表明着當前元素的集合,其兼容性如圖所示。
得到焦點的辦法
var btn = document.getElementsByTagName('button')[0];
btn.focus()
複製代碼
獲取當前焦點元素
判斷當前文檔內節點是否有焦點
參考文檔:
一、特性和屬性(Attributes and properties)
二、《JavaScript 高級程序設計》