DOM各版本css
DOM1主要定義的是 HTML 和 XML 文檔的底層結構html
DOM2 和 DOM3 級則在這個結構的基礎上引入了更多的交互能力,也支持了更高級的 XML 特性node
能夠經過下列代碼來肯定瀏覽器是否支持這些 DOM 模塊編程
var supportsDOM2Core = document.implementation.hasFeature("Core", "2.0"); var supportsDOM3Core = document.implementation.hasFeature("Core", "3.0"); var supportsDOM2HTML = document.implementation.hasFeature("HTML", "2.0"); var supportsDOM2Views = document.implementation.hasFeature("Views", "2.0"); var supportsDOM2XML = document.implementation.hasFeature("XML", "2.0");
針對XML命名空間的變化瀏覽器
XML命名空間app
命名空間要使用 xmlns 特性來指定,XHTML 的命名空間是 http://www.w3.org/1999/xhtm框架
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Example XHTML page</title> </head> <body> Hello world! </body> </html>
要想明確地爲 XML命名空間建立前綴,可使用 xmlns 後跟冒號,再後跟前綴dom
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"> <xhtml:head> <xhtml:title>Example XHTML page</xhtml:title> </xhtml:head> <xhtml:body> Hello world! </xhtml:body> </xhtml:html>
有時候爲了不不一樣語言間的衝突,也須要使用命名空間來限定特性svg
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"> <xhtml:head> <xhtml:title>Example XHTML page</xhtml:title> </xhtml:head> <xhtml:body xhtml:class="home"> Hello world! </xhtml:body> </xhtml:html>
在混合使用兩種語言的狀況下,命名空間的用處就很是大了函數
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Example XHTML page</title> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%; height:100%"> <rect x="0" y="0" width="100" height="100" style="fill:red"/> </svg> </body> </html>
Node 類型的變化
localName:不帶命名空間前綴的節點名稱。 namespaceURI:命名空間 URI 或者(在未指定的狀況下是)null。 prefix:命名空間前綴或者(在未指定的狀況下是)null 當節點使用了命名空間前綴時,其 nodeName 等於 prefix+":"+ localName <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Example XHTML page</title> </head> <body> <s:svg xmlns:s="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%; height:100%"> <s:rect x="0" y="0" width="100" height="100"style="fill:red"/> </s:svg> </body> </html>
DOM3 級在此基礎上更進一步,又引入了下列與命名空間有關的方法
isDefaultNamespace(namespaceURI):在指定的 namespaceURI 是當前節點的默認命名空間的狀況下返回 true。 lookupNamespaceURI(prefix):返回給定 prefix 的命名空間。 lookupPrefix(namespaceURI):返回給定 namespaceURI 的前綴 //針對前面的例子,能夠執行下列代碼 document.body.isDefaultNamespace("http://www.w3.org/1999/xhtml");//true //假設 svg 中包含着對<s:svg>的引用 alert(svg.lookupPrefix("http://www.w3.org/2000/svg")); //"s" alert(svg.lookupNamespaceURI("s")); //"http://www.w3.org/2000/svg"
Document 類型的變化
createElementNS(namespaceURI, tagName):使用給定的 tagName 建立一個屬於命名空間 namespaceURI 的新元素
createAttributeNS(namespaceURI, attributeName):使用給定的 attributeName 建立一個屬於命名空間 namespaceURI 的新特性
getElementsByTagNameNS(namespaceURI, tagName):返回屬於命名空間 namespaceURI的 tagName 元素的 NodeList
//建立一個新的 SVG 元素 var svg = document.createElementNS("http://www.w3.org/2000/svg","svg"); //建立一個屬於某個命名空間的新特性 var att = document.createAttributeNS("http://www.somewhere.com", "random"); //取得全部 XHTML 元素 var elems = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "*");
Element 類型的變化
NamedNodeMap 類型的變化
其餘方面的變化
DocumentType 類型的變化
DocumentType 類型新增了 3 個屬性:publicId、systemId 和 internalSubset
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd" [<!ELEMENT name (#PCDATA)>] >
前兩個屬性表示的是文檔類型聲明中的兩個信息段,這兩個信息段在 DOM1 級中是沒有辦法訪問到
alert(document.doctype.publicId);//-//W3C//DTD HTML 4.01//EN alert(document.doctype.systemId); //"http://www.w3.org/TR/html4/strict.dtd
最後一個屬性 internalSubset,用於訪問包含在文檔類型聲明中的額外定義
document.doctype.internalSubset//<!ELEMENT name (#PCDATA)>
Document 類型的變化
importNode():從一個文檔中取得一個節點,而後將其導入到另外一個文檔,使其成爲這個文檔結構的一部分;接受兩個參數,要複製的節點和一個表示是否複製子節點的布爾值;返回的結果是原來節點的副本,但可以在當前文檔中使用
var newNode = document.importNode(oldNode, true); //導入節點及其全部子節點 document.body.appendChild(newNode);
defaultView 的屬性:保存着一個指針,指向擁有給定文檔的窗口(或框架),在 IE 中有一個等價的屬性名叫 parentWindow(Opera 也支持這個屬性)
var parentWindow = document.defaultView || document.parentWindow;
document.implementation 對象的createDocumentType()方法:用於建立一個新的DocumentType節點,接受 3 個參數,文檔類型名稱、publicId、systemId
var doctype = document.implementation.createDocumentType("html", "-//W3C//DTD HTML 4.01//EN", "http://www.w3.org/TR/html4/strict.dtd");
document.implementation 對象的createDocument()方法:建立新文檔,法接受 3 個參數,針對文檔中元素的 namespaceURI、文檔元素的標籤名、新文檔的文檔類型
//建立一個空的新 XML 文檔 var doc = document.implementation.createDocument("", "root", null); //建立一個 XHTML 文檔 var doctype = document.implementation.createDocumentType("html", " -//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", doctype);
document.implementation對象的createHTMLDocument()方法:建立一個完整的 HTML 文檔,包括<html>、<head>、<title>、<body>
元素;這個方法只接受一個參數,即新建立文檔的標題題(放在<title>
裏的字符串),返回新的 HTML 文檔
var htmldoc = document.implementation.createHTMLDocument("New Doc"); alert(htmldoc.title); //"New Doc" alert(typeof htmldoc.body); //"object"
Node 類型的變化
isSupported()方法:法用於肯定當前節點具備什麼能力,這個方法也接受相同的兩個參數:特性名和特性版本號,若是瀏覽器實現了相應特性,並且可以基於給定節點執行該特性,就返回 true
if (document.body.isSupported("HTML", "2.0")){ //執行只有"DOM2 級 HTML"才支持的操做 }
isSameNode()和 isEqualNode()方法:接受一個節點參數,並在傳入節點與引用的節點相同或相等時返回 true;所謂相同,指的是兩個節點引用的是同一個對象。所謂相等,指的是兩個節點是相同的類型,具備相等的屬性(nodeName、nodeValue,等等),並且它們的 attributes 和 childNodes 屬性也相等(相同位置包含相同的值)
var div1 = document.createElement("div"); div1.setAttribute("class", "box"); var div2 = document.createElement("div"); div2.setAttribute("class", "box"); alert(div1.isSameNode(div1)); //true alert(div1.isEqualNode(div2)); //true alert(div1.isSameNode(div2)); //false
setUserData()方法:會將數據指定給節點,它接受 3 個參數:要設置的鍵、實際的數據(能夠是任何數據類型)和處理函數;處理函數會在帶有數據的節點被複制、刪除、重命名或引入一個文檔時
調用,於是你能夠事先決定在上述操做發生時如何處理用戶數據。處理函數接受 5 個參數:表示操做類型的數值(1 表示複製,2 表示導入,3 表示刪除,4 表示重命名)、數據鍵、數據值、源節點和目標節點。在刪除節點時,源節點是 null;除在複製節點時,目標節點均爲 null
//如下代碼能夠將數據指定給一個節點 document.body.setUserData("name", "Nicholas", function(){}); //而後,使用 getUserData()並傳入相同的鍵,就能夠取得該數據 var value = document.body.getUserData("name"); //在函數內部,你能夠決定如何存儲數據 var div = document.createElement("div"); div.setUserData("name", "Nicholas", function(operation, key, value, src, dest){ if (operation == 1){ dest.setUserData(key, value, function(){}); } }); var newDiv = div.cloneNode(true); alert(newDiv.getUserData("name")); //"Nicholas"
框架的變化
框架和內嵌框架分別用 HTMLFrameElement 和 HTMLIFrameElement 表示,它們在 DOM2級中都有了一個新屬性,名叫 contentDocument:包含一個指針,指向表示框架內容的文檔對象
var iframe = document.getElementById("myIframe"); var iframeDoc = iframe.contentDocument; //在 IE8 之前的版本中無效
IE8 以前不支持框架中的 contentDocument 屬性,但支持一個名叫 contentWindow 的屬性,該屬性返回框架的 window 對象,而這個 window 對象又有一個 document 屬性
var iframe = document.getElementById("myIframe"); var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
概念:
在 HTML 中定義樣式的方式有 3 種:經過<link/>
元素包含外部樣式表文件、使用<style/>
元素
定義嵌入式樣式,以及使用 style 特性定義針對特定元素的樣式
肯定瀏覽器是否支持 DOM2 級定義的 CSS 能力:
var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0"); var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");
訪問元素的樣式
概念
任何支持 style 特性的 HTML 元素在 JavaScript 中都有一個對應的 style 屬性;
對於使用短劃線(分隔不一樣的詞彙,例如 background-image)的 CSS 屬性名,必須將其轉換成駝峯大小寫形式,才能經過 JavaScript 來訪問;
float 是 JavaScript 中的保留字,所以不能用做屬性名,應該轉爲cssFloat,IE支持的則是 styleFloat
只要取得一個有效的 DOM 元素的引用,就能夠隨時使用 JavaScript 爲其設置樣式
var myDiv = document.getElementById("myDiv"); //設置背景顏色 myDiv.style.backgroundColor = "red"; //改變大小 myDiv.style.width = "100px"; myDiv.style.height = "200px"; //指定邊框 myDiv.style.border = "1px solid black";
經過 style 對象一樣能夠取得在 style 特性中指定的樣式
//<div id="myDiv" style="background-color:blue;width:10px;height:25px"></div> alert(myDiv.style.backgroundColor); //"blue" alert(myDiv.style.width); //"10px" alert(myDiv.style.height); //"25px"
若是沒有爲元素設置 style 特性,那麼 style 對象中可能會包含一些默認的值,但這些值並不能準確地反映該元素的樣式信息
DOM 樣式屬性和方法
計算的樣式
getComputedStyle()方法:兩個參數,要取得計算樣式的元素和一個僞元素字符串(例如":after")若是不須要僞元素信息,第二個參數能夠是 null。getComputedStyle()方法返回一個 CSSStyleDeclaration 對象(與 style 屬性的類型相同),其中包含當前元素的全部計算的樣式
<!DOCTYPE html> <html> <head> <title>Computed Styles Example</title> <style type="text/css"> #myDiv { background-color: blue; width: 100px; height: 200px; } </style> </head> <body> <div id="myDiv" style="background-color: red; border: 1px solid black"> </div> <script> var myDiv = document.getElementById("myDiv"); var computedStyle = document.defaultView.getComputedStyle(myDiv, null); alert(computedStyle.backgroundColor); // "red" alert(computedStyle.width); // "100px" alert(computedStyle.height); // "200px" alert(computedStyle.border); // 在某些瀏覽器中是"1px solid black" </script> </body> </html>
在 IE 中,每一個具備 style 屬性的元素還有一個 currentStyle 屬性。這個屬性是 CSSStyleDeclaration 的實例,包含當前元素所有計算後的樣式
var myDiv = document.getElementById("myDiv"); var computedStyle = myDiv.currentStyle; alert(computedStyle.backgroundColor); //"red" alert(computedStyle.width); //"100px" alert(computedStyle.height); //"200px" alert(computedStyle.border); //undefined
操做樣式表
檢測瀏覽器是否支持 DOM2 級樣式表
var supportsDOM2StyleSheets = document.implementation.hasFeature("StyleSheets", "2.0");
CSSStyleSheet 繼承自 StyleSheet,後者能夠做爲一個基礎接口來定義非 CSS 樣式表。從StyleSheet 接口繼承而來的屬性以下:
<link>
和<style>
元素media特性值的字符串<link>
或<style/>
引入的(在 XML 中多是經過處理指令引入的)。若是當前樣式表是其餘樣式表經過偏移量
//取得元素的左偏移量 function getElementLeft(element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; while (current !== null){ actualLeft += current.offsetLeft; current = current.offsetParent; } return actualLeft; } //取得元素的上偏移量 function getElementTop(element){ var actualTop = element.offsetTop; var current = element.offsetParent; while (current !== null){ actualTop += current. offsetTop; current = current.offsetParent; } return actualTop; }
客戶區大小
function getViewport(){ if (document.compatMode == "BackCompat"){ return { width: document.body.clientWidth, height: document.body.clientHeight }; } else { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }; } }
滾動大小
scrollHeight:在沒有滾動條的狀況下,元素內容的總高度
scrollWidth:在沒有滾動條的狀況下,元素內容的總寬度
scrollLeft:被隱藏在內容區域左側的像素數。經過設置這個屬性能夠改變元素的滾動位置
scrollTop:被隱藏在內容區域上方的像素數。經過設置這個屬性能夠改變元素的滾動位置
IE(在標準模式)中 scrollWidth 和 scrollHeight 等於文檔內容區域的大小,而 clientWidth 和 clientHeight 等於視口大小
在肯定文檔的總高度時(包括基於視口的最小高度時),必須取得 scrollWidth/clientWidth 和
scrollHeight/clientHeight 中的最大值,才能保證在跨瀏覽器的環境下獲得精確的結果
var docHeight = Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight); var docWidth = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth);
對於運行在混雜模式下的 IE,則須要用 document.body 代替 document.documentElement
經過 scrollLeft 和 scrollTop 屬性既能夠肯定元素當前滾動的狀態,也能夠設置元素的滾動位
置
function scrollToTop(element){ if (element.scrollTop != 0){ element.scrollTop = 0; } }
肯定元素大小
每一個元素都有一個 getBoundingClientRect()方法,返回會一個矩形對象,包含 4 個屬性:left、top、right 和 bottom
function getBoundingClientRect(element){ var scrollTop = document.documentElement.scrollTop; var scrollLeft = document.documentElement.scrollLeft; if (element.getBoundingClientRect){ if (typeof arguments.callee.offset != "number"){ var scrollTop = document.documentElement.scrollTop; var temp = document.createElement("div"); temp.style.cssText = "position:absolute;left:0;top:0;"; document.body.appendChild(temp); arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop; document.body.removeChild(temp); temp = null; } var rect = element.getBoundingClientRect(); var offset = arguments.callee.offset; return { left: rect.left + offset, right: rect.right + offset, top: rect.top + offset, bottom: rect.bottom + offset }; } else { var actualLeft = getElementLeft(element); var actualTop = getElementTop(element); return { left: actualLeft - scrollLeft, right: actualLeft + element.offsetWidth - scrollLeft, top: actualTop - scrollTop, bottom: actualTop + element.offsetHeight - scrollTop } } }
檢測瀏覽器對 DOM2 級遍歷能力的支持狀況
var supportsTraversals = document.implementation.hasFeature("Traversal", "2.0"); var supportsNodeIterator = (typeof document.createNodeIterator == "function"); var supportsTreeWalker = (typeof document.createTreeWalker == "function");
NodeIterator
可使用 document.createNodeIterator()方法建立它的新實例,這個方法接受下列 4 個參數
舉例:
var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);
兩個主要方法是 nextNode()和 previousNode(),在深度優先的 DOM 子樹遍歷中,nextNode()方法用於向前前進一步,而 previousNode()用於向後後退一步。因爲 nextNode()和 previousNode()方法都基於 NodeIterator 在 DOM 結構中的內部指針工做,因此 DOM 結構的變化會反映在遍歷的結果中。
<div id="div1"> <p><b>Hello</b> world!</p> <ul> <li>List item 1</li> <li>List item 2</li> <li>List item 3</li> </ul> </div> <script> var div = document.getElementById("div1"); var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, null, false); var node = iterator.nextNode(); while (node !== null) { alert(node.tagName); //輸出標籤名 node = iterator.nextNode(); } </script>
TreeWalker
DOM中的範圍
建立範圍:使用createRange()方法
//檢測瀏覽器是否支持範圍 var supportsRange = document.implementation.hasFeature("Range", "2.0"); var alsoSupportsRange = (typeof document.createRange == "function"); //建立 var range = document.createRange();
DOM2 級規範定義了一些模塊,用於加強 DOM1 級。「DOM2 級核心」爲不一樣的 DOM 類型引入了一些與 XML 命名空間有關的方法。這些變化只在使用 XML 或 XHTML 文檔時纔有用;對於 HTML 文檔沒有實際意義。除了與 XML 命名空間有關的方法外,「DOM2 級核心」還定義了以編程方式建立Document 實例的方法,也支持了建立 DocumentType 對象。
「DOM2 級樣式」模塊主要針對操做元素的樣式信息而開發,其特性簡要總結以下:
每一個元素都有一個關聯的 style 對象,能夠用來肯定和修改行內的樣式。
要肯定某個元素的計算樣式(包括應用給它的全部 CSS 規則),可使用 getComputedStyle()方法
IE不支持 getComputedStyle()方法,但爲全部元素都提供了可以返回相同信息 currentStyle屬性
能夠經過 document.styleSheets 集合訪問樣式表
除 IE 以外的全部瀏覽器都支持針對樣式表的這個接口,IE 也爲幾乎全部相應的 DOM 功能提供了本身的一套屬性和方法。
「DOM2 級遍歷和範圍」模塊提供了與 DOM 結構交互的不一樣方式,簡要總結以下:
遍歷即便用 NodeIterator 或 TreeWalker 對 DOM 執行深度優先的遍歷
NodeIterator 是一個簡單的接口,只容許以一個節點的步幅先後移動。而 TreeWalker 在提供相同功能的同時,還支持在 DOM 結構的各個方向上移動,包括父節點、同輩節點和子節點等方向
範圍是選擇 DOM 結構中特定部分,而後再執行相應操做的一種手段
使用範圍選區能夠在刪除文檔中某些部分的同時,保持文檔結構的格式良好,或者複製文檔中的相應部分
IE8 及更早版本不支持「DOM2 級遍歷和範圍」模塊,但它提供了一個專有的文本範圍對象,能夠用來完成簡單的基於文本的範圍操做。IE9 徹底支持 DOM 遍歷