JavaScript學習 8、DOM擴展

對DOM的兩個主要擴展是Selectors API(選擇符API)和HTML5.這兩個擴展都是源自開發社區。此外還有一個不那麼由於矚目的ELement Traversal(元素遍歷)規範。爲DOM添加了一些屬性。javascript

選擇符API

 衆多JavaScript 庫中最經常使用的一項功能,就是根據CSS選擇符選擇與某個模式匹配的DOM元素。 實際上 jQuery 的核心就是經過CSS選擇符查詢DOM 文檔取得元素的引用,從而拋開了 getElementById() 和 getElementsByTagName()。html

selectors API Level 1 的核心是兩個方法:querySelector() 和 querySelectorAll()。在兼容的瀏覽器中,能夠經過Document 及 Element 類型的實例調用它們。目前已經徹底支持 Selectors API Level 1的瀏覽器有 IE 8+、Firefox 3.5+、Safari 3.1+、Chrome 和 Opera 10+。java

querySelector() 方法接收一個CSS 選擇符,返回與該模式匹配的第一個元素,若是沒有找到匹配的元素,返回null。node

querySelectorAll() 方法也是接收一個CSS 選擇符,返回一個NodeList 類型的實例。web

上面兩個方法若是傳入了瀏覽器不支持的選擇符或者選擇符中有語法錯誤,則會拋出錯誤。瀏覽器

元素遍歷

 對於元素之間的空格,IE9及以前的版本不會返回文本節點,而其餘全部瀏覽器都會返回文本節點。這樣就致使了在使用childNodes 和 fristChild 等屬性時的行爲不一致。爲了彌補這一差別,而同時有保持DOM規範不變,Element Traversal 規範 新定義了一組屬性。安全

Element Traversal API 爲DOM 元素添加了如下 5個屬性。app

  • childElementCount:返回子元素(不包括文本節點和註釋)的個數。
  • firstElementChild:指向第一個子元素;firstChild 的元素版。
  • lastElementChild:指向最後一個子元素;lastChild的元素版。
  • previousElementSibling:指向前一個同輩元素;previousSibling 的元素版。
  • nextElementSibling:指向後一個同輩元素;nextSibling 的元素版。

支持Element Traversal 規範的瀏覽器有 IE9+、 Firefox3.5+、Safari 4+、Chrome 和 Opera 10+。iphone

 

HTML5

 HTML5 規範圍繞如何使用新增標記定義了大量的JavaScript API。其中一些API與DOM重疊,定義了瀏覽器應該支持的DOM 擴展。函數

與類相關的擴充

class 屬性在 HTML文檔中應用愈來愈多,一方面能夠經過它爲元素添加樣式,另外一方面還能夠用它表示元素的語義。爲了簡化CSS類的用法,HTML5新增了不少相關的API。

1.getElementsByClassName() 方法

能夠經過document對象及全部HTML 元素調用該方法。該方法接收一個參數,即一個包含一個或多個類名的字符串,返回帶有指定類的全部元素的NodeList。傳入多個類名是,類名的前後順序不重要。

var allCurrentUserNames = document.getElementsByClassName("username current");

var selected = document.getElementById("myDiv").getElementsByClassName("selected");

 

支持getElementsByClassName() 的瀏覽器有 IE9+、 Firefox3+、Safari 3.1+、Chrome 和 Opera 9.5+。

2.classList 屬性

因爲calssName 中是一個字符串,因此若是想刪除或修改某個類名時,就要分析整個字符串,方法以下:

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <div class="bd user disabled">testdiv</div>
        <script type="text/javascript">
        var allDiv = document.getElementsByClassName("disabled bd");
        var div = allDiv[0];

        var classNames = div.className.split(/\s+/);
        //find className
        var pos = -1, i, len;
        for(i=0, len=classNames.length; i<len; i++){
            if(classNames[i] == "user"){
                pos = i;
                break;
            }
        }

        //delete className
        classNames.splice(i, 1);

        //join
        div.className = classNames.join(" ");
        </script>
    </body>
</html>

 

HTML5 新增了一個操做類名的方式,可讓操做更加簡單也更安全,那就是爲全部元素添加了classList 屬性。這個classList 屬性是新集合類型 DOMTokenList 的實例,與其餘集合同樣,DOMTokenList 有一個表示本身包含多少元素的 length 屬性,而要取得每一個元素可使用 item() 方法,也能夠又使用方括號語法。另外這個新類型還有以下方法:

  • add(value):將給定的字符串值添加到列表中。若是值已經存在就不添加了。
  • contains(value):表示列表中是否存在給定的值,若是存在則返回true,不然返回false。
  • remove(value):從列表中刪除給定的字符串。
  • toggle(value):若是列表中已經存在給定的值,則刪除它;若是沒有,則添加它。

因此上例中的一坨代碼就能夠簡化成一條:

div.classList.remove("user");

 

 支持classList 屬性的瀏覽器有 Firefox3.6+ 和 Chrome。

焦點管理

HTML5 中添加了輔助管理DOM焦點的功能,首先就是 document.activeElement 屬性,這個屬性始終會引用DOM中當前得到了焦點的元素。元素得到焦點的方式有頁面加載、用戶輸入(一般是經過按Tab鍵)和在代碼中調用 focus() 方法。

var button = document.querySelector("#mybutton");
button.focus();
alert(document.activeElement == button);  //true

默認狀況下,文檔剛剛加載完成時,document.activeElement 中保存的是 document.body 元素的引用。文檔加載期間,document.activeElement 的值是 null。

另外新增了 document.hasFocus() 方法,這個方法用於判肯定文檔是否得到了焦點。

實現了者兩個屬性的瀏覽器包括 IE4+、Firefox 3+、Safari 4+、 Chrome 和 Opera 8+。

HTMLDocument 的變化

HTML5 擴展了 HTMLDocument,增長了新的功能。

1.readyState 屬性

Document的 readyState 屬性有兩個可能的值:

  • loading,正在加載的文檔;
  • complete,已經加載完文檔。

使用document.readyState 的最恰當的方式,就是經過它來實現一個指示文檔已經加載完成的指示器。

支持readyState 屬性的瀏覽器有 IE4+、Firefox3.6+、Safari 、Chrome 和 Opera 9+ 。

2.兼容模式

document.compateMode 的 值等於 「CSS1Compat」表示瀏覽器在標準模式下。document.compatMode 值等於「BackCompat」 表示瀏覽器在混雜模式下。

3.head屬性

相似於 document.body HTML5 增長了 document.head 屬性來引用文檔的 <head> 元素。能夠結合使用這個屬性和另外一種後備方法。

var head = document.head || document.getElementsByTagName("head")[0];

 

4.自定義數據屬性

HTML5規定能夠爲元素添加非標準的屬性,可是要添加前綴 data-,目的是爲元素提供與渲染無關的信息,或者提供語義信息。這些屬性能夠任意添加、隨便命名,只要以data- 開頭便可。

添加了自定義屬性以後,能夠經過元素的dataset 屬性來訪問自定義屬性的值。dataset 屬性的值是一個DOMStringMap 的實例,也就是一個名值對兒的映射。在這個映射中,每一個data-name 形式的屬性都會有一個對應的屬性,只不過屬性名沒有 data- 前綴。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <button id="mybutton" data-apptype="iphone" data-myname="AJ">pushme</button>
        <script type="text/javascript">
        var button = document.querySelector("#mybutton");
        var appType = button.dataset.apptype;
        var myname = button.dataset.myname;
        alert(appType + "  "  + myname);

        button.dataset.apptype = "Android";
        button.dataset.myname = "LL";

        if(button.dataset.myname){
            alert("Hello " + button.dataset.myname);
        }

        </script>
    </body>
</html>

 

 注意:以上代碼中 dataset 後面的屬性不能夠用大寫,由於HTML中屬性都會被變成小寫,因此JavaScript 中也必須使用小寫才能訪問。

 支持自定義數據屬性的瀏覽器有Firefox 6+ 和 Chrome。

5.插入標記

innerHTML屬性返回與調用元素的全部子節點對應的HTML標記,寫入innerHTML 時會根據指定的值建立新的DOM樹,而後用這個DOM樹徹底替換調用元素原先全部的子節點。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <div id="content">
            <p>This is a <strong>paragraph</strong> with a list following it.</p>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
            </ul>

        </div>
        <script type="text/javascript">
            var div = document.getElementById("content");
            alert(div.innerHTML);
            /**
            <p>This is a <strong>paragraph</strong> with a list following it.</p>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
            </ul>
            */
            div.innerHTML = "Hello World!";
        </script>
    </body>
</html>

 

 outerHTML屬性,返回調用它的元素及全部子節點的HTML標籤。在寫入的狀況下,outerHTML會根據指定的HTML 字符串建立新的DOM子樹,而後用這個DOM子樹徹底替換調用的元素。

6. scrollIntoView() 方法

scrollIntoView() 能夠在全部 HTML元素上調用,經過滾動瀏覽器窗口或者某個容器元素,調用元素就能夠出如今視口中。若是給這個方法傳入true 做爲參數,或者不傳入任何參數,那麼窗口滾動以後會然調用元素的頂部與視口頂部儘可能平齊。若是傳入false 做爲參數,調用元素會盡量所有出如今視口中。不過頂部不必定平齊。

document.forms[0].scrollIntoView(); 

專有擴展

 1.children 屬性

children屬性是一個HTMLCollection 實例,值包含元素重一樣仍是元素的子節點,除此以外 children 和 childNode沒有什麼區別,即在元素值包含元素子節點時,者兩個屬性的值相同。

2.contains() 方法

contains 方法用於肯定某個節點(參數)是否是被檢測節點的後代節點。是則返回true 不然返回false。

除此以外還可使用 DOM Level 3 中的 compareDocumentPosition() 方法來肯定節點之間的關係。返回一個表示該關係的位掩碼(bitmask)。掩碼值以下:

  • 1:無關(給定的節點不在當前文檔中)
  • 2:居前(給定的節點在DOM樹中位於參考節點以前)
  • 4:居後(給定的節點在DOM樹中位於參考節點以後)
  • 8:包含(給定的節點是參考節點的祖先)
  • 16:被包含(給定的節點是參考節點的後代)

一個通用的contains() 函數能夠寫成以下形式:

function contains(refNode, otherNode){
    if(typeof refNode.contains == "function" &&
        (!client.engine.webkit || client.engine.webkit>522)){
        return refNode.contains(otherNode);
    }else if(typeof refNode.compareDocumentPosition == "function"){
        return !!(refNode.compareDocumentPosition(otherNode) & 16);
    }else{
        var node = otherNode.parentNode;
        do{
            if(node == refNode){
                return true;
            }else{
                node = node.parentNode;
            }
        }while(node != null);
        return false;
    }
}

 

 

小結

 雖然DOM 爲與XML及HTML 文檔交互制定了一系列核心API,但仍然有幾個規範會標準的DOM進行了擴展。這些擴展中有不少原來是瀏覽器轉悠的,但後來成爲了事實標準,因而其餘瀏覽器也都提供了相同的實現。

  • Selectors API,定義了兩個方法,讓開發人員可以基於CSS選擇符從DOM 中取得元素,這兩個方法是 querySelector() 和 querySelectorAll()。
  • Element Traversal,爲DOM元素定義了額外的屬性,讓開發人員可以更方便地從一個元素跳到另外一個元素。之因此會出現這個擴展,是由於瀏覽器處理DOM元素間空白符的方式不同。
  • HTML5, 爲標準的DOM 定義了不少擴展功能。其中包括在innerHTML屬性這樣的事實標準基礎上提供的標準定義,以及爲管理焦點、設置字符集、滾動頁面而規定的擴展API。
相關文章
相關標籤/搜索