看完JavaScript高級程序設計,整理了一下里面的DOM這一塊的知識點,比較多,比較碎!DOM在整個頁面的地位如圖:javascript
DOM(文檔對象模型)是針對HTML 和XML 文檔的一個API(應用程序編程接口)。DOM描,繪了一個層次化的節點樹,容許開發人員添加、移除和修改頁面的某一部分.css
DOM 能夠將任何HTML 或XML 文檔描繪成一個由多層節點構成的結構。節點分爲幾種不一樣的類型,每種類型分別表示文檔中不一樣的信息及(或)標記。每一個節點都擁有各自的特色、數據和方法,另外也與其餘節點存在某種關係。節點類型如圖:html
一、節點的公共屬和方法java
nodeType ——節點的類型,9表明Document節點,1表明Element節點,3表明Text節點,8表明Comment節點,11表明DocumentFragment節點node
nodeName ——元素的標籤名(如P,SPAN,#text(文本節點),DIV),以大寫形式表示chrome
nodeVlue ——Text節點或Comment節點的文本內容編程
childNodes—–獲取子節點瀏覽器
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
parentNode——獲取父節點markdown
firstNode——獲取第一個子節點app
lastNode——獲取最後一個子節點
nextSibling——獲取下一個兄弟節點
previousSibling——獲取上一個兄弟節點
ownerDocument——獲取文檔節點
hasChildNodes()——判斷是否有子節點
appendChild()——添加子節點,接收一個參數表示要添加的節點,返回添加的節點.
var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
//插入後成爲第一個子節點
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
//替換第一個子節點
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);
//移除第一個子節點
var formerFirstChild = someNode.removeChild(someNode.firstChild);
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或7(其餘瀏覽器) var shallowList = myList.cloneNode(false); alert(shallowList.childNodes.length); //0
deepList.childNodes.length
中的差別主要是由於IE8 及更早版本與其餘瀏覽器處理空白字符的方式不同。IE9 以前的版本不會爲空白符建立節點。
cloneNode()方法不會複製添加到DOM 節點中的JavaScript 屬性,例如事件處理程序等。這個方法只複製特性、(在明確指定的狀況下也複製)子節點,其餘一切都不會複製。IE 在此存在一個bug,即它會複製事件處理程序,因此咱們建議在複製以前最好先移除事件處理程序。
上述節點的nodeName 和 nodeValue對應下圖:
JavaScript 經過Document 類型表示文檔。在瀏覽器中,document 對象是HTMLDocument(繼承自Document 類型)的一個實例,表示整個HTML 頁面。並且,document 對象是window 對象的一個屬性,所以能夠將其做爲全局對象來訪問
一、document對象的屬性和方法
var html = document.documentElement; //取得對<html>的引用
alert(html === document.childNodes[0]); //true
alert(html === document.firstChild); //true
body——獲取body節點元素
title——獲取title文字節點元素
//取得文檔標題
var originalTitle = document.title;
//設置文檔標題
document.title = "New page title";
URL——取得完整的URL
domain——取得域名
referrer——取得來源頁面的URL
//取得完整的URL
var url = document.URL;
//取得域名
var domain = document.domain;
//取得來源頁面的URL
var referrer = document.referrer;
document.anchors——包含文檔中全部帶name 特性的元素
document.forms——包含文檔中全部的元素,與document.getElementsByTagName(「form」)獲得的結果相同
document.images——包含文檔中全部的元素,與document.getElementsByTagName(「img」)獲得的結果相同;
document.links——包含文檔中全部帶href 特性的元素。
二、DOM的操做
getElementById()——經過id屬性獲取元素
getElementsByTagName()——經過元素名獲取元素
var div = document.getElementById("myDiv"); //取得id='myDiv'元素的引用
var images = document.getElementsByTagName("img"); //取得img元素的引用
var allElements = document.getElementsByTagName("*"); //獲取文檔中全部的元素
IE7及較低版本還爲此方法添加了一個有意思的「怪癖」:name特性與給定ID匹配的表單元素也會被該方法返回
三、DOM一致性檢測
因爲 DOM 分爲多個級別,也包含多個部分,所以檢測瀏覽器實現了DOM的哪些部分就十分必要了。document.implementation
屬性就是爲此提供相應信息和功能的對象,與瀏覽器對DOM的實現直接對應。DOM1 級只爲document.implementation 規定了一個方法,即hasFeature()
。這個方法接受兩個參數:要檢測的DOM功能的名稱及版本號。若是瀏覽器支持給定名稱和版本的功能,則該方法返回true。
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
如下爲列出了能夠檢測的不一樣的值及版本號
一、HTML元素
全部 HTML 元素都由HTMLElement 類型表示,不是直接經過這個類型,也是經過它的子類型來表示。HTMLElement 類型直接繼承自Element 並添加了一些屬性。添加的這些屬性分別對應於每一個HTML元素中都存在的下列標準特性。
id ——元素在文檔中的惟一標識符。
title ——有關元素的附加說明信息,通常經過工具提示條顯示出來。
lang ——元素內容的語言代碼,不多使用。
dir ——語言的方向,值爲」ltr」(left-to-right,從左至右)或」rtl」(right-to-left,從右至左),也不多使用。
className ——與元素的class 特性對應,即爲元素指定的CSS類。沒有將這個屬性命名爲class,是由於class 是ECMAScript 的保留字
<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>
var div = document.getElementById("myDiv");
alert(div.id); //"myDiv""
alert(div.className); //"bd"
alert(div.title); //"Body text"
alert(div.lang); //"en"
alert(div.dir); //"ltr"
div.id = "someOtherId";
div.className = "ft";
div.title = "Some other text";
div.lang = "fr";
div.dir ="rtl";
二、特性操做
有三個方法能夠操做元素的特性
getAttribute()
setAttribute()
removeAttribute()
var div = document.getElementById("myDiv");
alert(div.getAttribute("id")); //"myDiv"
alert(div.getAttribute("class")); //"bd"
div.setAttribute("id", "someOtherId");
div.setAttribute("class", "ft");
div.setAttribute("title", "Some other text");
div.removeAttribute("class");
有兩類特殊的特性,它們雖然有對應的屬性名,但屬性的值與經過getAttribute()返回的值並不相同。第一類特性就是style,用於經過CSS 爲元素指定樣式。在經過getAttribute()訪問時,返回的style 特性值中包含的是CSS 文本,而經過屬性來訪問它則會返回一個對象。
第二類不同凡響的特性是onclick 這樣的事件處理程序。當在元素上使用時,onclick 特性中包含的是JavaScript 代碼,若是經過getAttribute()訪問,則會返回相應代碼的字符串. IE6 及之前版本不支持removeAttribute()。
三、attributes 屬性
Element類型是使用attributes屬性的惟一一個DOM節點類型,attributes屬性是NamedNodeMap類型的對象,它有如下幾個方法
var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;
element.attributes["id"].nodeValue = "someOtherId";
因爲attributes的方法不夠方便,所以開發人員更多的會使用getAttribute()、removeAttribute()和setAttribute()方法。
四、建立元素
document.createElement()
——方法能夠建立新元素。這個方法只接受一個參數,即要建立元素的標籤名。var div = document.createElement('div');
div.id = 'myDiv';
div.className = 'box';
在 IE 中能夠以另外一種方式使用createElement(),即爲這個方法傳入完整的元素標籤,也能夠包含屬性,以下面的例子所示。
var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >");
這種方式有助於避開在IE7 及更早版本中動態建立元素的某些問題。
文本節點由 Text 類型表示,包含的是能夠照字面解釋的純文本內容。純文本中能夠包含轉義後的HTML 字符,但不能包含HTML代碼。
使用下列方法能夠操做節點中的文本
appendData(text):將text 添加到節點的末尾。
deleteData(offset, count):從offset 指定的位置開始刪除count 個字符。
insertData(offset, text):在offset 指定的位置插入text。
replaceData(offset, count, text):用text 替換從offset 指定的位置開始到offset+count爲止處的文本
splitText(offset):從offset 指定的位置將當前文本節點分紅兩個文本節點
substringData(offset, count):提取從offset 指定的位置開始到offset+count 爲止處的字符串建立文本節點
createTextNode()——能夠建立文本節點.
var textNode = document.createTextNode("<strong>Hello</strong> world!");
下面展現如何將一個文本節點添加到文檔中
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
合併文本節點
一個元素可能會存在多個文本節點,可是文本節點之間也沒有空格,所以沒法區分哪一個節點對應的是哪一個文本,經過下面的方法能夠將element元素的文本節點合併.
var newNode = element.firstChild.splitText(5);從位置5 開始。位置5是"Hello"和"world!"之間的空格
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2
注意提醒:
一、innerText、textContent innerText與textContent的區別,當文本爲空時,innerText是」「,而textContent是undefined
二、innerHTML與innerText的區別,就是對HTML代碼的輸出方式Text不會輸出HTML代碼.
一、選擇符API
Selectors API Level 1 的核心是兩個方法:
- querySelector()
- querySelectorAll()。
在兼容的瀏覽器中,能夠經過Document 及Element 類型的實例調用它們。目前已徹底支持Selectors API Level 1的瀏覽器有IE 8+、Firefox 3.5+、Safari 3.1+、Chrome 和Opera 10+。
querySelector()方法
//取得body 元素
var body = document.querySelector("body");
//取得ID 爲"myDiv"的元素
var myDiv = document.querySelector("#myDiv");
//取得類爲"selected"的第一個元素
var selected = document.querySelector(".selected");
//取得類爲"button"的第一個圖像元素
var img = document.body.querySelector("img.button");
querySelectorAll()方法
//取得某<div>中的全部<em>元素(相似於getElementsByTagName("em"))
var ems = document.getElementById("myDiv").querySelectorAll("em");
//取得類爲"selected"的全部元素
var selecteds = document.querySelectorAll(".selected");
//取得全部<p>元素中的全部<strong>元素
var strongs = document.querySelectorAll("p strong");
二、HTML5與類相關的擴充
//取得全部類中包含"username"和"current"的元素,類名的前後順序無所謂
var allCurrentUsernames = document.getElementsByClassName("username current");
支持 getElementsByClassName()方法的瀏覽器有IE 9+、Firefox 3+、Safari 3.1+、Chrome 和
Opera 9.5+。
這個屬性指向的是當前得到焦點的元素,使用focus()可讓元素得到焦點
var button = document.getElementById("myButton");
button.focus();
alert(document.activeElement === button); //true
document.hasFocus()
這個方法用於肯定文檔是否得到了焦點
var button = document.getElementById("myButton");
button.focus();
alert(document.hasFocus()); //true
實現了這兩個屬性的瀏覽器的包括IE 4+、Firefox 3+、Safari 4+、Chrome 和Opera 8+。
HTMLDocument的變化
document.readyState
表示文檔的加載進度,它有兩個值分別爲’loading’和’complete’.
if(document.readyState == 'complete'){
//執行操做
}
支持 readyState 屬性的瀏覽器有IE4+、Firefox 3.6+、Safari、Chrome 和Opera 9+。
document.compatMode
屬性告訴開發人員瀏覽器採用了哪一種渲染模式。在標準模式下,document.compatMode 的值等於」CSS1Compat」,而在混雜模式下document.compatMode 的值等於」BackCompat」。
if (document.compatMode == "CSS1Compat"){
alert("Standards mode");
} else {
alert("Quirks mode");
}
兼容性:IE、Firefox、Safari 3.1+、Opera 和Chrome
字符編碼——document.charset
當前文檔的字符編碼
document.defaultCharset——當前文檔的默認字符編碼
三、自定義數據屬性
HTML5 規定能夠爲元素添加非標準的屬性,但要添加前綴data-,目的是爲元素提供與渲染無關的信息,或者提供語義信息。
<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>
var div = document.getElementById("myDiv");
//取得自定義屬性的值
var appId = div.dataset.appId;
var myName = div.dataset.myname;
//設置值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
if (div.dataset.myname){
alert("Hello, " + div.dataset.myname);
}
支持自定義數據屬性的瀏覽器有Firefox 6+和Chrome
插入標記
在讀模式下,innerHTML 屬性返回與調用元素的全部子節點(包括元素、註釋和文本節點)對應
的HTML 標記。在寫模式下,innerHTML 會根據指定的值建立新的DOM樹,而後用這個DOM樹徹底
替換調用元素原先的全部子節點
在讀模式下,outerHTML 返回調用它的元素及全部子節點的HTML 標籤。在寫模式下,outerHTML
會根據指定的HTML 字符串建立新的DOM 子樹,而後用這個DOM子樹徹底替換調用元素。
四、內存與性能問題
使用本節介紹的方法替換子節點可能會致使瀏覽器的內存佔用問題,尤爲是在IE 中,問題更加明顯。在刪除帶有事件處理程序或引用了其餘JavaScript 對象子樹時,就有可能致使內存佔用問題。假設某個元素有一個事件處理程序(或者引用了一個JavaScript 對象做爲屬性),在使用前述某個屬性將該元素從文檔樹中刪除後,元素與事件處理程序(或JavaScript 對象)之間的綁定關係在內存中並無一併刪除。若是這種狀況頻繁出現,頁面佔用的內存數量就會明顯增長。所以,在使用innerHTML、outerHTML 屬性方法時,最好先手工刪除要被替換的元素的全部事件處理程序和JavaScript 對象屬性
//讓元素可見
document.forms[0].scrollIntoView();
DOM2 和DOM3級分爲許多模塊(模塊之間具備某種關聯),分別描述了DOM 的某個很是具體的子集。這些模塊以下
在 HTML 中定義樣式的方式有3 種:經過<link/>
元素包含外部樣式表文件、使用<style/>
元素定義嵌入式樣式,以及使用style 特性定義針對特定元素的樣式。「DOM2 級樣式」模塊圍繞這3 種應用樣式的機制提供了一套API。要肯定瀏覽器是否支持DOM2 級定義的CSS 能力,可使用下列代碼
var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");
一、訪問元素的樣式
任何支持 style 特性的HTML 元素在JavaScript 中都有一個對應的style 屬性。訪問和設置元素的css屬性能夠這樣操做:
var div = document.getElementById('myDiv');
console.log(div.style.color); //獲取color值
div.style.color = 'red'; //設置color值
div.style.fontSize = '20px';//設置font-size的值(這裏會將有短橫線的值轉化爲駝峯命名來獲取或設置)
注:IE6+,chrome,firfox支持這種獲取或設置css的方式.這裏有一個特例,因爲float是保留關鍵字,因此經過cssFloat來訪問和設置,而IE中則經過styleFloat來設置或訪問.
元素的style對象除了有css的樣式屬性外,也包含了本身的一些屬性,具體以下:
//設置style對象的cssText屬性
myDiv.style.cssText = "width: 25px; height: 100px; background-color: green";
alert(myDiv.style.cssText);
二、操做樣式表
CSSStyleSheet 類型表示的是樣式表,包括經過<link>
元素包含的樣式表和在<style>
元素中定義的樣式表,使用下面的代碼能夠肯定瀏覽器是否支持DOM2 級樣式表:
var supportsDOM2StyleSheets =document.implementation.hasFeature("StyleSheets", "2.0");
CSSStyleSheet 繼承自StyleSheet,後者能夠做爲一個基礎接口來定義非CSS 樣式表。從StyleSheet 接口繼承而來的屬性以下:
<link>
包含的,則是樣式表的URL;不然,是null。media:當前樣式表支持的全部媒體類型的集合。與全部DOM 集合同樣,這個集合也有一個length 屬性和一個item()方法。也可使用方括號語法取得集合中特定的項。若是集合是空列表,表示樣式表適用於全部媒體。在IE 中,media 是一個反映<link>
和<style>
元素media特性值的字符串。
ownerNode:指向擁有當前樣式表的節點的指針,樣式表多是在HTML 中經過<link>
或<style/>
引入的(在XML 中多是經過處理指令引入的)。若是當前樣式表是其餘樣式表經過@import 導入的,則這個屬性值爲null。IE 不支持這個屬性。
parentStyleSheet:在當前樣式表是經過@import 導入的狀況下,這個屬性是一個指向導入它的樣式表的指針。
除了 disabled 屬性以外,其餘屬性都是隻讀的。在支持以上全部這些屬性的基礎上,CSSStyleSheet 類型還支持下列屬性和方法:
應用於文檔的全部樣式表是經過 document.styleSheets 集合來表示的。也能夠直接經過<link>
或<style>
元素取得CSSStyleSheet 對象。DOM 規定了一個包含CSSStyleSheet 對象的屬性,名叫sheet;除了IE,其餘瀏覽器都支持這個屬性。IE 支持的是styleSheet屬性
三、元素大小
客戶區大小
有關客戶區大小的屬性有兩個:clientWidth
和clientHeight
。其中,clientWidth 屬性是元素內容區寬度加上左右內邊距寬度;clientHeight 屬性是元素內容區高度加上上下內邊距高度
滾動大小
IE、Firefox 3+、Safari 4+、Opera 9.5 及Chrome 爲每一個元素都提供了一個getBoundingClientRect()方法。這個方法返回會一個矩形對象,包含4 個屬性:left、top、right 和bottom。這些屬性給出了元素在頁面中相對於視口的位置。可是,瀏覽器的實現稍有不一樣。IE8 及更早版本認爲文檔的左上角座標是(2, 2),而其餘瀏覽器包括IE9 則將傳統的(0,0)做爲起點座標。所以,就須要在一開始檢查一下位於(0,0)處的元素的位置,在IE8 及更早版本中,會返回(2,2),而在其餘瀏覽器中會返回(0,0).
遍歷
DOM2 級遍歷和範圍」模塊定義了兩個用於輔助完成順序遍歷DOM 結構的類型:NodeIterator
和TreeWalker
。這兩個類型可以基於給定的起點對DOM 結構執行深度優先(depth-first)的遍歷操做。
在與DOM 兼容的瀏覽器中(Firefox 1 及更高版本、Safari 1.3 及更高版本、Opera 7.6 及更高版本、Chrome0.2 及更高版本),均可以訪問到這些類型的對象。IE 不支持DOM 遍歷。使用下列代碼能夠檢測瀏覽器
對DOM2 級遍歷能力的支持狀況。
var supportsTraversals = document.implementation.hasFeature("Traversal", "2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == "function");
var supportsTreeWalker = (typeof document.createTreeWalker == "function");
範圍
爲了讓開發人員更方便地控制頁面,「DOM2 級遍歷和範圍」模塊定義了「範圍」(range)接口。經過範圍能夠選擇文檔中的一個區域,而沒必要考慮節點的界限(選擇在後臺完成,對用戶是不可見的)。在常規的DOM 操做不能更有效地修改文檔時,使用範圍每每能夠達到目的。Firefox、Opera、Safari 和Chrome 都支持DOM 範圍。IE 以專有方式實現了本身的範圍特性。
參考:
- JavaScript高級程序設計
- javascript之DOM操做