javascript快速入門14--DOM基礎

水之原發表於2013-12-01

DOM(Document Object Model)——文件物件模型

什麼是DOM?

Document Object Model (DOM)是HTML和XML文件的程式設計介面。它提供了上述文件的一種結構化表示,同時也定義了一種通過程式來改變文件結構,風格,以及內容的方式。DOM用一組結構化的節點以及物件來表示文件。本質上就是將網頁和指令碼語言以及程式語言連線起來。

一個網頁是一個文件。這個文件可以被顯示在瀏覽器視窗中,也可以以html原始碼的形式顯示。這兩中情況中,文件都是同一個。DOM提供了另一種方式來表示,儲存,操作這個文件。DOM是網頁的一種完全的物件導向的表示方法,可以通過指令碼語言(比如說JavaScript)來改變。

W3C DOM標準形成了當今大多數瀏覽器的DOM基礎。許多瀏覽器提供超出W3C標準的擴充套件,所以當用在可能被擁有不同DOM的各種瀏覽器使用的場合時 一定要多加註意

DOM標準主要要為:微軟DOM與W3C DOM,一般IE實現的是微軟DOM,而其它瀏覽器則不同程度的實際了W3C DOM

DOM發展史

  • DOM Level Zero ,事實上從來不存在DOM 0版本,只是人們的戲稱。只是在W3C DOM出現之前,不同瀏覽器(主要是IE與NN)實現的DOM相互排斥,1996年的瀏覽器大戰所產生的DHTML就是所謂的DOM 0,它是指令碼程式設計師的惡夢
  • DOM Level 1 包括DOM Core和DOM HTML。前者提供了基於XML的文件結構圖。後者新增了一些HTML專用的物件和方法,從而擴充套件了DOM Core.目前IE在內的大部分桌面瀏覽器都通過不同方式實現了DOM 1
  • DOM Level 2 引入幾個新模組:DOM檢視,事件,樣式,遍歷和範圍。IE只實現了一部分,火狐瀏覽器幾乎全部實現,除IE之外的瀏覽器也實現了大部分
  • DOM Level 3 引入了以統一的方式載入和儲存文件的方法。DOM Core被擴充套件支援所有的XML1.0的特性。火狐瀏覽器之類實現了少部分

在開始階段,JavaScript和DOM是緊密的聯絡在一起的,但是最終他們將發展為獨立的實體。網頁的內容儲存在DOM中並且可以被JavaScript訪問和處理,所以我們可以得到寫下這個近似的等式:
API(網頁或者XML頁面)=DOM + JS(指令碼語言)

DOM被設計為獨立於任何特定的程式語言,通過協調一致的API以確保這種文件的結構化表現形式是有效的。雖然DOM的實現可以建立在任何語言上,但是在這裡我們專注於JavaScript上的DOM實現!

儘管DOM很大程度上受到瀏覽器中動態HTML發展的影響,但W3C還是將它最先應用於XML。

DOM與BOM的關係

DOM與BOM的關係?——BOM包含DOM

DOM與BOM結構檢視

DOM Core

文件物件模型-DOM,就是使用樹檢視來形容HTML程式碼,看下面的一張HTML頁面的原始碼

    <html>
        <head>
            <title>樹!樹!到處都是樹!</title>
        </head>
        <body>
            <h1>樹!樹!到處都是樹!</h1>
            <p>HTML那層層巢狀的程式碼就像一棵<em></em>一樣!</p>
            <div>一層一層的樹<img src="../images/stach_heap.gif" /> </div>
        </body>
    </html>

 

瀏覽器接受該頁面並將之轉換為樹形結構

獲取元素常用方法

document物件是BOM的一部分,同時也是HTML DOM的HTMLDocument物件的一種表現形式,反過來說,它也是XML DOM Document物件。JavaScript中的大部分處理DOM的過程都利用document物件,所以我們訪問文件需要使用BOM提供的這個入口。

    var d = document;
    alert(d);//這僅僅表明document這個物件是存在的

 

document物件有三個強大的方法,可以獲取頁面的任何元素

    var p1 = document.getElementById("p1");//獲取ID為p1的那個元素
    //在一個文件中ID必須是唯一的,getElementById方法只會返回一個元素
    alert(p1.tagName);
    var allP = document.getElementsByTagName("p");//獲取文件中所有p標籤
    //因為頁面中標籤相同的元素很多,所以即使頁面中只有一個p元素,getElementsByTagName也會返回一個集合
    for (var i=0;i < allP.length;i++) {
        alert(allP[i].innerHTML);//像陣列一樣訪問其中的每個元素
    }
    //getElementsByTagName還可以使用萬用字元*來獲取所有的元素
    var allTags = document.getElementsByTagName("*");
    alert(allTags.length);
    //更強大的是,getElementsByTagName不但可以在document物件上呼叫,也可以在其它HTML元素上呼叫
    var p2 = document.getElementById("p2");
    var p2ps = p2.getElementsByTagName("em");//將獲取p2下面的em元素,而不獲取p2之外的em
    //還有一個通過name來獲取元素的方法:getElementsByName
    var radios = document.getElementsByName("check");//獲取所有name為check的元素

 

由於name可以重複,getElementsByName方法始終返回一個集合,不管頁面中name是否是唯一的。 IE 6.0和Opera 7.5在這個方法的使用上還存在一些錯誤。首先,它們還會返回id等於給定名稱的元素。第二,它們僅僅檢查<input/>和<img/>元素。

獲取和設定元素屬性——getAttribute與setAttribute方法

    var p1 = document.getElementById("p1");
    alert(p1.getAttribute("id"));
    p1.setAttribute("title","Value");

 

節點基礎

文件根節點

    var de = document.documentElement;
    alert(de.tagName);

 

由於IE 5.5中的DOM實現的錯誤,document.documentElement會返回<body/>元素。IE 6.0已經修復了這個錯誤。

獲取head與body

    //本來可以使用getElementsByTagName的
    var head = document.getElementsByTagName("head")[0];
    var body = document.getElementsByTagName("body")[0];

 

還可以使用節點,在使用節點前,先了解一些節點基礎知識

常用節點型別

  • 元素節點——文件中具有標籤的節點
  • 文字節點——標籤中不是註釋的文字塊

常用的節點屬性

  • nodeType——節點型別,元素節點是1,文字節點是3
  • nodeValue——節點值,元素節點為空,文字節點的nodeValue屬性即為文字內容
  • firstChild——該元素節點包含的第一個子節點
  • lastChild——該元素節點包含的最後一個子節點
  • nextSibling——該節點的後一個兄弟節點
  • previousSibling——該節點的前一個兄弟節點
  • childNodes——子節點列表,可以通過node.childNodes[index](或node.childNodes.item(index))來獲取子節點
  • nodeName——節點名稱,對於元素節點,返回tagName,對於文字,則返回#text

考慮下面的HTML程式碼所表示的節點結構

    <p> Some Text </p>

 

上面的HTML程式碼將會解析成兩個節點:元素節點——p標籤,文字節點——Some Text.也就是說,標籤中包含的一些文字也是節點,那麼空格之類的非列印字元會不會被當作文字節點呢?

不同瀏覽器在判斷何為Text節點上存在一些差異。某些瀏覽器,如Mozilla,認為元素之間的空白(包括換行符)都是Text節點;而另一些瀏覽器,如IE,會全部忽略這些空白!!

    var de = document.documentElement;
    var head = de.firstChild;//html下面第一個元素,可能是head
    var body = de.lastChild;//html下面最後一個元素,可能是body

 

答案並不確定,但是仍然有辦法解決——使用節點型別檢測,每個節點都有nodeType屬性,指明它的節點型別。對於元素節點,它的值是1,而對於文字節點,它的值是3

    var de = document.documentElement;
    var head = de.firstChild.nodeType==1?de.firstChild:de.firstChild.nextSibling;
    var body = de.lastChild.nodeType==1?de.lastChild:de.lastChild.previousSibling;]
    //還可以使用childNodes
    var de = document.documentElement;
    var head = de.childNodes[0].nodeType==1?de.childNodes[0]:de.childNodes[0].nextSibling;
    var head = de.childNodes[1].nodeType==1?de.childNodes[1]:de.childNodes[1].previousSibling;

 

HTML DOM

HTML DOM用物件來表示HTML標籤,考慮下面的程式碼——

    <img src="../images/stack_heap.jpg" alt="記憶體堆疊" onclick="alert('Hello!')"  />
    //對於上面的img標籤,瀏覽器解析時會將其轉換成下面的物件
    {
        src:"../images/stack_heap.jpg",
        alt:"記憶體堆疊",
        onclick:"alert('Hello!')",
        tagName:"IMG"
    };
    //其實不止這些屬性

 

一般所說的DOM是指XML DOM,而W3C也為HTML頁面提供了更快捷的DOM——HTML DOM!使用HTML DOM,能使訪問HTML標籤的屬性就像訪問JavaScript建立的物件的屬性一樣簡單.

    var imgObj = document.getElementById("imgObj");
    alert(imgObj.src);//獲取src屬性如此簡單

 

使用HTML DOM也使得訪問頁面一些元素變得更加簡單

    var bodyTag = document.documentElement.lastChild;//DOM標準方式
    bodyTag = document.body;//HTML DOM方式
    var titleTag = document.getElementsByTagName("title")[0].firstChild.nodeValue;//DOM標準方式
    titleTag = document.title;//HTML DOM方式
    //HTML DOM不僅僅可以用來獲取內容,也可以設定
    document.title ="Change The Title!!!";

 

相關文章