DOM1級主要定義了文檔的底層結構,並提供了基本的查詢操作的API,總體而言這些API已經比較完善,我們可以通過這些API完成大部分的DOM操作。然而,為了擴展DOM API的功能,同時進一步提高DOM操作的效率,DOM擴展也不斷被提出和採納。對DOM的擴展主要有兩部分:Selectors API和...
DOM1級主要定義了文檔的底層結構,並提供了基本的查詢操作的API,總體而言這些API已經比較完善,我們可以通過這些API完成大部分的DOM操作。然而,為了擴展DOM API的功能,同時進一步提高DOM操作的效率,DOM擴展也不斷被提出和採納。對DOM的擴展主要有兩部分:Selectors API和HTML5,另外還有一個Element Traversal規範,主要用於元素遍歷,另外還有一些專有擴展。
1 Selectors API
Selectors API主要實現根據CSS選擇符來查詢匹配的文檔元素,事實上這個功能是很多JavaScript庫(如jquery)都提供的功能。selectors API level 1的核心是兩個函數:querySelector()和querySelectorAll(),這兩個方法都接收一個參數,即CSS選擇器,前者只返回與選擇器匹配的第一個元素,後者則是返回匹配的所有元素的NodeList。這兩個函數在使用時需要註意: (1) 如果傳入的選擇器是瀏覽器不支持的或者存在語法錯誤時,這兩個方法都會報錯。 (2)可以調用這個方法的節點類型包括Document,Element和DocumentFragment。 Selectors API的瀏覽器支持情況如下:IE8只能支持CSS2.1中的選擇器格式,對於 :nth-child()等CSS3中的選擇器是不支持的。
Selectors API LEVEL2增加了一個方法為matchesSelector,用來檢查調用元素是否符合傳入的css選擇器。截止到2011年還沒有瀏覽器真正實現了matchesSelector方法,樓主測試了最新版的chrome和firefox,同樣也沒有實現這個方法,但是各個瀏覽器都有實驗性的方法,比如IE實現了msMatchesSelector,firefox實現了mozMatchesSelector,safari和chrome實現了webkitMatchesSelector方法,如果需要使用該方法,則需要進行必要的能力檢測。
2 Element Traversal API
我們曾介紹過,IE9及以上的瀏覽器會把元素間的空白或換行也作為parentNode的childNodes屬性中的一個item,從而為我們遍歷元素造成一定障礙,Element Traversal API為元素增加了以下幾個屬性: [1]firstChildElement:第一個孩子元素 [2]lastChildElement:最後一個孩子元素 [3]previousElementSibling:上一個相鄰的元素 [4]nextElementSibing:下一個相鄰的元素 [5]childElementCount:元素子節點的數目
使用這幾個API就不需要考慮文本節點和註釋節點所帶來的影響了,這樣我們遍歷一個Element的代碼就可以由原來的:
function traversal(element){
var childNodes = element.childNodes,i = 0, len = childNodes.length, item;
for(; i < len ; i++){
item = childNodes.item([i]);
if(item.nodeType === 1){
console.log(item.nodeName + ":" + item.innerHTML);
}
}
}
演變為:
function traversalNewVersion(element){
var len = element.childElementCount, child = element.firstElementChild;
while(true){
console.log(child.nodeName + ":" + child.innerHTML);
if(child === element.lastElementChild){
break;
}
child = child.nextElementSibling;
}
}
註:IE9+,Firefox3.5+,chrome,Opera10+,Safari4+支持Element Traversal API
3 HTML5對DOM節點的擴展
HTML5對DOM節點的操作也增加了一些API,這一節主要介紹HTML5對DOM節點的擴展。
3.1 與類有關的擴展
隨著WEB開發的不斷發展,出現了一個現象:class運用得越來越多,一方面通過class為元素設置css樣式,另一方面class還能代表一定的語義性質,為此,HTML5為DOM的class特性操作確定了相應的擴展,主要包括: 3.1.1 getElementsByClassName getElementsByClassName可以根據class特性選擇元素,返回的是一個NodeList,它接收一個參數,即class特性字元串,class的先後順序不會影響元素的查找。比如我們的DOM中有如下兩個元素:
<p class="red strong">我是第一個段落</p>那麼我們調用:
<p class="green strong bigger">我是較大的段落</p>
var paragraphs = document.getElementsByClassName("strong red");仍然可以查找到第一個段落元素, getElementsByClassName的瀏覽器支持情況如下:
3.1.2 classList屬性 HTML中,一個元素可能會有多個class特性,每一個class特性之間用空格分隔,這樣如果想要對class特性進行修改或者增加class特性的話,必須對字元串進行處理。大部分JavaScript類庫都實現了操作class特性相關的方法,而HTML中為元素增加了一個classList屬性,從而可以方便地實現對class特性的操作,這個屬性是新集合類型DOMTokenList的實例,它也有一個length屬性,同時還定義瞭如下方法: (1)add(value):為元素增加一個class類 (2)contains(value):判斷元素是否包含一個class (3)remove(value):刪除一個class (4)toggle(value):如果包含這個類,則刪除;如果不包含,則增加。 有了這些方法,我們操作class列表時就非常方便了,classList的瀏覽器支持情況如下圖:
3.2 焦點管理 HTML5中也新增了管理DOM焦點的功能,主要是document的兩個屬性: (1) document.activeElement: 這個引用始終指向當前頁面取得焦點的元素,頁面載入完畢時,它指向document.body。 (2)document.hasFocus:用於獲取當前文檔是否獲得了焦點,從而判斷頁面是不是正在與用戶進行交互。 這兩個屬性最大的功能是提高web應用的無障礙性。
註:IE4+,Firefox3+,chrome,Opera8+,Safari4+支持這兩個屬性HTML5對HTMLDocument也做了擴展,增加了新的屬性和功能,這些 變化也是基於大部分瀏覽器已經完全支持的專有擴展而來,因此雖然這些變化寫入標準的時間不長,但是有些瀏覽器可能很早就已經支持相應的功能了。 3.3.1 readyState IE4首先為document設置了readyState屬性,其他瀏覽器也陸續增加了這個屬性,HTML最終將這個屬性寫入了標準。在IE中,document的readyState屬性包括兩個值: [1]loading:正在載入文檔 [2]complete:文檔載入結束 我們看下標準中對readyState的闡述:
3.3 HTMLDocument的變化
註:IE4+,Firefox3.6+,chrome,Opera9+,Safari支持這兩個屬性
3.3.2 相容模式
從IE6開始區分渲染頁面的模式是標準還是混雜的,檢測頁面的相容模式就成為瀏覽器的必要功能。IE為此添加了一個compatMode屬性用來標識頁面渲染是標準模式還是混雜模式。如果是標準模式,這個屬性值為"CSS1Compat",而如果是混雜模式,這個屬性值為"BackCompat"
除IE為,Firefox,chrome,Opera,Safari3.1+也都實現了這個屬性,並最終被HTML納入標準之中。
3.3.3 head屬性
document.head可以引用頁面中的<head>元素,當然還可以通過document.getElementsByTagName("head")[0]來引用<head>元素。
註:IE10+也支持這個屬性
3.4 字元集屬性
HTML5新增了幾個和字元集有關的屬性,主要包括:
(1)lcharset:表示文檔中實際使用的字元集,這個屬性既可以通過<meta>標簽來修改,也可以通過返回的http頭部設置,還可以修改charset屬性來設置。另外,firefox中支持characterSet屬性,這個屬性是只讀的。
註:chrome45之後將charset屬性設置成了只讀的,IE 8及以下不支持characterSet屬性
(2)defaultCharset:預設的字元集是什麼,這個屬性和瀏覽器或操作系統的設置有關係。
註:firefox不支持defaultCharset
3.5 自定義屬性
HTML5規定可以為元素添加非標準的屬性,但要添加一個"data-"首碼,目的是提供與渲染無關的信息或提供語義化的信息,比如我們有以下代碼:
<div id="div" data-author="劉木林" data-uuid="123" data-age="23"></div>
一個元素的自定義屬性保存在dataset屬性中,這個值是DOMStringMap的實例,也就是一個鍵值對的映射。在這個映射中,每一個自定義屬性都會有一個對應的屬性,只不過這個屬性名沒有了data-首碼,我們仍然以上面的代碼為例:
var div = document.getElementById("div");
var data = div.dataset;
console.log(data.author);
輸出的結果就是:劉木林
目前dataset屬性的支持情況如下:IE10及以下和opera mini為"Partial support",意思是可以通過getAttribute("data-")來獲取自定義屬性,比如上例中:
alert(div.getAttribute("data-author"));那麼也會彈出:劉木林
未完待續~~