JavaScript DOM

DOM簡介( Document Object Model 文檔對象模型)

W3C

W3C 文檔對象模型 (DOM) 是中立於平臺和語言的接口,它容許程序和腳本動態地訪問和更新文檔的內容、結構和樣式。
W3C DOM 標準被分爲 3 個不一樣的部分:javascript

  • 核心 DOM - 針對任何結構化文檔的標準模型css

  • XML DOM - 針對 XML 文檔的標準模型html

  • HTML DOM - 針對 HTML 文檔的標準模型前端

也就是說,DOM包含三個版本(?),對應不一樣的DOM模型,因爲我對XML還不是很瞭解,這裏主要先討論HTML DOMjava

關於XML DOM 的W3C文檔:XML DOM 教程

MDN:DOM概述

XML與HTML的區別

XML DOM解析 基礎概念


什麼是 HTML DOM

引自W3C:node

  • HTML的標準對象模型

  • HTML 的標準編程接口

  • W3C 標準

  • HTML DOM 定義了全部 HTML 元素的對象和屬性,以及訪問它們的方法。
    換言之,HTML DOM 是關於如何獲取、修改、添加或刪除 HTML 元素的標準jquery

引自MDN:web

文檔對象模型 (DOM) 是HTMLXML文檔的編程接口。它提供了對文檔的結構化的表述,並定義了一種方式可使從程序中對該結構進行訪問,從而改變文檔的結構,樣式和內容。DOM 將文檔解析爲一個由節點和對象(包含屬性和方法的對象)組成的結構集合。簡言之,它會將web頁面和腳本或程序語言鏈接起來。編程

一個web頁面是一個文檔。這個文檔能夠在瀏覽器窗口或做爲HTML源碼顯示出來。但上述兩個狀況中都是同一份文檔。文檔對象模型(DOM)提供了對同一份文檔的另外一種表現,存儲和操做的方式。 DOM是web頁面的徹底的面向對象表述,它可以使用如 JavaScript等腳本語言進行修改。json

咱們之因此可以對Web頁面進行添加、刪除、更新、操控元素等等活動,就是由於這個DOM才得以實現。它定義了一套對象(方法)規則,使得JavaScript能夠根據這些規則來進行編程。更像是一個文檔API


DOM 節點(Node

根據 W3C 的 HTML DOM 標準,HTML 文檔中的全部內容都是節點:

  • 整個文檔是一個文檔節點

  • 每一個HTML元素是元素節點

  • HTML元素內的文本是文本節點

  • 每一個HTML屬性是屬性節點

  • 註釋是註釋節點

節點樹

HTML DOM 將 HTML 文檔視做樹結構。這種結構被稱爲節點樹:
圖片描述
圖片描述
圖片描述

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>     
    <body>
        <h1>Temperature Conversion</h1>
        <p>
            <input type="text" id="temperature" />
            <input type="button" id="f_to_c" value="F to C" />
            <input type="button" id="c_to_f" value="C to F" />
        </p>
        <!-- Computation result will go here-->
        <p id="result"></p>
        <script src="temperature.js"></script>
    </body>
</html>

這也被稱爲W3C DOM 1級核心

W3C的DOM Level 1 Core是用於更改文檔內容樹的強大對象模型。全部主流瀏覽器都支持Mozilla Firefox和Microsoft Internet Explorer。它是網絡上腳本編寫的強大基礎。

怎麼稱呼這些元素?

例:

<html>
  <head>
    <title>DOM 教程</title>
  </head>
  <body>
    <h1>DOM 第一課</h1>
    <p>Hello world!</p>
  </body>
</html>
  • <html> 節點沒有父節點;它是根節點

  • <head><body> 的父節點是 <html> 節點

  • 文本節點 "Hello world!" 的父節點是 <p> 節點

  • <html> 節點擁有兩個子節點:<head><body>

  • <head> 節點擁有一個子節點:<title> 節點

  • <title> 節點也擁有一個子節點:文本節點 "DOM 教程"

  • <h1><p> 節點是同胞節點,同時也是 <body> 的子節點

而且

  • <head> 元素是 <html> 元素的首個子節點

  • <body> 元素是 <html> 元素的最後一個子節點

  • <h1> 元素是 <body> 元素的首個子節點

  • <p> 元素是 <body> 元素的最後一個子節點

DOM 處理中的常見錯誤是但願元素節點包含文本。

在本例中:<title>DOM 教程</title>,元素節點 <title>,包含值爲 "DOM 教程" 的文本節點


HTML DOM

首先記住這個:

HTML DOM (文檔對象模型)中,每一個部分都是節點:

  • 文檔自己是文檔節點

  • 全部HTML元素是元素節點

  • 全部 HTML 屬性是屬性節點

  • HTML元素內的文本是文本節點

  • 註釋是註釋節點


DOM Document

每一個載入瀏覽器的 HTML 文檔都會成爲 Document 對象。

Document對象使咱們能夠從腳本中對 HTML 頁面中的全部元素進行訪問。

提示:Document 對象是 Window 對象的一部分,可經過 window.document 屬性對其進行訪問。

document.URL

  • URL 屬性可返回當前文檔的 URL。
    好比在如今的窗口下,控制檯輸入:

alert(document.URL)

圖片描述


document.getElementById()

這個你們都很熟悉了,getElementById() 方法可返回對擁有指定 ID 的第一個對象的引用。

W3C還定義了一個工具函數:getElementById() 是一個重要的方法,在 DOM 程序設計中,它的使用很是常見。咱們爲您定義了一個工具函數,這樣您就能夠經過一個較短的名字來使用 getElementById() 方法了:

function id(x) {
      if (typeof x == "string") return document.getElementById(x);
      return x;
  }
  // 上面這個函數接受元素 ID 做爲它們的參數。使用前編寫 x = id(x) 就能夠了。

document.getElementsByName()

getElementsByName() 方法可返回帶有指定名稱的對象的集合

該方法與 getElementById() 方法類似,可是它查詢元素的 name 屬性,而不是 id 屬性。
另外,由於一個文檔中的 name 屬性可能不惟一(如 HTML 表單中的單選按鈕一般具備相同的 name 屬性),全部 getElementsByName() 方法返回的是元素的數組,而不是一個元素。

因爲這個方法返回的是一個數組,不是具體的元素,因此必須注意這點:

<input type="text" value="" name="myinput"/>
    <input type="button" value="" name="myinput" id="ID"/>
    
    <script type="text/javascript">
        var inputA = document.getElementsByName("myinput")[0]; // [0]表示得到的全部input元素中第一個
        var inputB = document.getElementById("ID");            // ID取值則很精確,由於ID的特殊性
        
        var iA = inputA.attributes;             // 元素自帶對象,內含該元素全部屬性(以鍵值對存在)
        alert(iA.length);                       // 3
        alert(iA[0].name+" : "+iA[0].value);    // "type : text"
        
        var iB = inputB.attributes;
        alert(iB.length);                       // 4
        alert(iB[0].name+" : "+iB[0].value);    // "type : button"
    </script>

document.getElementsByTagName()

注意要和上面的區分,TagName指的是標籤名

getElementsByTagName() 方法可返回帶有指定標籤名的對象的集合,返回元素的順序是它們在文檔中的順序。

若是把特殊字符串 "*" 傳遞給 getElementsByTagName() 方法,它將返回文檔中全部元素的列表,元素排列的順序就是它們在文檔中的順序。

註釋:傳遞給 getElementsByTagName() 方法的字符串能夠不區分大小寫。

<input type="text" />
    <input type="text" />
    <input type="text" />
    <script type="text/javascript">
        var x = document.getElementsByTagName("INPUT")[0];
        alert(x.tagName)            // "INPUT"
    </script>

document.write()

write() 方法可向文檔寫入 HTML 表達式或 JavaScript 代碼。
可列出多個參數(exp1,exp2,exp3,...) ,它們將按順序被追加到文檔中。

document.write("Hello World!");

關於Document的更多屬性方法可查W3C:HTML DOM Document 對象


DOM Element

簡介:

  • 在 HTML DOM 中,Element 對象表示 HTML 元素(全部 HTML 元素是元素節點)。

  • Element 對象能夠擁有類型爲元素節點、文本節點、註釋節點的子節點。

  • NodeList 對象表示節點列表,好比 HTML 元素的子節點集合。

  • 元素也能夠擁有屬性。屬性是屬性節點(參見DOM Attribute)。


element.parentNode

parentNode 屬性以 Node 對象的形式返回指定節點的父節點。
若是指定節點沒有父節點,則返回 null

<div>
        <h1>H1</h1>
    </div>
    <script type="text/javascript">
        var h = document.getElementsByTagName("H1")[0];
        alert(h.parentNode.nodeName);                // "DIV"
    </script>

element.style

HTMLElement.style 屬性返回一個 CSSStyleDeclaration 對象,表示元素的 內聯style 屬性(attribute),但忽略任何樣式表應用的屬性。 經過 style 能夠訪問的 CSS 屬性列表,能夠查看 CSS Properties Reference。

<div>
        <h1>H1</h1>
    </div>
    <script type="text/javascript">
        var h = document.getElementsByTagName("H1")[0];
        h.setAttribute("style","font-size:100px;color: blue;")
    </script>

圖片描述

elt.style.cssText = "color: blue"; 設置多個樣式屬性

elt.setAttribute("style", "color: blue"); 設置多個樣式屬性

elt.style.color = "blue"; 直接設置樣式屬性

var st = elt.style; st.color = "blue"; 間接設置樣式屬性

一般,要了解元素樣式的信息,僅僅使用 style 屬性是不夠的,這是由於它只包含了在元素內嵌 style 屬性(attribute)上聲明的的 CSS 屬性,而不包括來自其餘地方聲明的樣式,如 <head> 部分的內嵌樣式表,或外部樣式表。要獲取一個元素的全部 CSS 屬性,你應該使用 window.getComputedStyle()。


element.childNodes;

childNodes 屬性返回節點的子節點集合,以 NodeList 對象。

提示:您可使用 length 屬性來肯定子節點的數量,而後您就可以遍歷全部的子節點並提取您須要的信息。

Node.childNodes 返回包含指定節點的子節點的集合,該集合爲即時更新的集合(live collection)。

  • 得到的Nodelist是實時更新的,若是你新增一個子節點,下次調用chilNodes屬性返回的Nodelist會變化(更新)。

  • Nodelist不是數組!這一點很重要


<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>     
    <body>
        <div>this is div
            <h1 id="h1">this is H1</h1>
            <h2>this is H2</h2>
        </div>
        
        <div id="div2">這是DIV2的文本節點<p>Element P</p></div>
        <hr />
        <script type="text/javascript">
            var div = document.getElementsByTagName("div")[0];
            var child_nodes = div.childNodes;
            var h1 = document.getElementsByTagName("h1")[0];
            var h2 = document.getElementsByTagName("h2")[0];
            
// 爲了看Nodelist裏有什麼東西,for循環出來一堆看不懂的東西:)        
            for (var i=0;i<child_nodes.length;i++) {            // 遍歷這個Nodelist,並寫入document文檔中
                    document.write(child_nodes[i]+"<br />")
            }
            document.write("<br />");
// Nodelist有length屬性,這裏值爲5,而且它能夠刪除掉
            console.log(child_nodes.length);                    // 5
            delete child_nodes.length;             
            console.log(child_nodes.length);                    // "undefined"
/**Nodelist裏元素(節點)對象排序按照HTML源碼的順序排下來,第一個文本節點從div標籤後開始,到H1標籤前,在Nodelist裏表示就是[0]
 * 第二個是H1元素節點,可是H1標籤後有換行空餘,這裏構成了H1標籤後面的文本節,即Nodelist[2]
 * 同理,H2標籤後由於換行符,到DIV結束標籤前產生的空餘內容構成了Nostlist[4]
 */
            console.log(child_nodes[0].nodeType);                // nodeType:3,表示文本
            console.log(child_nodes[1]===h1)                    // true
            child_nodes[1].style.background = "orange";            // 返回的Nodelist由於包括子節點,能夠設置樣式
// div的Nodelist裏[2][11]的文本節點是什麼?    result:是由於H1,H2元素節點換行產生的空餘,這裏由於能夠填充文本因此也算是文本節點
            
            console.log(h1.childNodes.length);        // 1
// H1元素的Nodelist裏只有文本節點,哪怕沒有像<p></p>裏添加任何東西,仍是存在這個文本節點

// 再使用一個全新的div來試驗,div2咱們不讓它產生空隙
            var div2 = document.getElementById("div2").childNodes;
            for (var j=0;j<div2.length;j++) {
                document.write(j+1+"個"+div2[j]+"<br />")
            }
/*咱們能夠看到,這樣就只有兩個Node,第一個是DIV文本,第二個是P元素節點,
 * 從<div>到</div>結束,之間全部的內容都是div的子節點,包括未處理文本,可是這一特性在不一樣瀏覽器上也不同
 * 第一個DIV,若是用IE解釋,它的Nodelist只有三個節點,其餘瀏覽器就有5個子節點*/
        </script>
    </body>
</html>

MDN:Node.childNodesNodeList

深刻理解 NodeList - 挨踢前端 - 博客園

因爲這個特性,因此通常推薦使用.childrenjQuery 遍歷 - children() 方法


DOM Attribute

Attr 對象

  • 在 HTML DOM 中,Attr 對象表示 HTML 屬性

  • HTML 屬性始終屬於 HTML 元素。


NamedNodeMap 對象

  • 在 HTML DOM 中,NamedNodeMap 對象表示元素屬性節點的無序集合

  • NamedNodeMap 中的節點可經過名稱或索引(數字)來訪問


<input type="text"  id="ID" value="VALUE" class="CLASS"/>
            <br />
            <hr />
            <script type="text/javascript">
                var Input = document.getElementsByTagName("input")[0];
//                console.log(Input.attributes)        //  "[object NamedNodeMap]"

                for (var b in Input) {                // 查看input元素節點裏的屬性方法
                    document.write(b+"<br />")
                }
                document.write("<hr />")            
                for (var j in Input.attributes) {    // input.attributes,即NameNodeMap對象
                    document.write(j+"<br />")
                }
                document.write("<hr />")            
                for (var x in Input.attributes[0]) {    // input元素節點裏的屬性節點,每一個HTML標準屬性都是一個屬性節點
                    document.write(x+"<br />")
                }

for-in出來的東西太多就不貼圖了


DOM元素含有的這兩個東西,雖然徹底不是一回事,但卻又緊密聯繫在一體,不細細體會,還真很差分清。Property-屬性Attribute-特性,每個dom元素都有一個attributes屬性來存放全部的attribute節點,經過getAttribute()setAttribute()方法來進行獲取和操做。

Property就是一個屬性,若是把DOM元素當作是一個普通的object對象,那麼property就是以name=value形式存放在Object中的屬性操做很簡單

element.gameid = 880; // 添加
console.log( elem.gameid ) // 獲取

這兩個東西有什麼聯繫和區別呢?
首先,不少attribute節點有一個相應的property屬性,如例子中的input元素的idtype既是attribute也有property,無論哪一種方式均可以訪問和修改,可是對於自定義的attribute節點,或者自定義property,二者就沒有關係了,對於IE6-7來講,沒有區分attributeproperty。具體的講解能夠考attributeproperty的區別,很詳細。

這段話也是我在百度知道上找的,目前個人理解也很不全面,先擺着之後慢慢看。先知道怎麼使用這些屬性節點和NameNodeMap對象。後續要弄懂分清除PropertyAttrubute兩個對象

引用幾個很有見地的文章吧:

attribute

input節點有不少屬性(attribute):‘type’,'id','value','class'以及自定義屬性,在DOM中有setAttribute()和getAttribute()讀寫DOM樹節點的屬性(attribute)

PS:在這裏的getAttribute方法有一個潛規則,部分屬性(input的value和checked)經過getAttribut取到的是初始值

Property

javascript獲取到的DOM節點對象,好比a 你能夠將他看做爲一個基本的js對象,這個對象包括不少屬性(property),好比「value」,「className」以及一些方法,setAttribute,getAttribute,onclick等,

全部在平常的工做中,推薦是使用 property,這樣事情處理起來比較簡單一些,attribute永遠是字符串。

來看幾個經常使用屬性/方法


  • 獲取、設置、刪除屬性節點經常使用方法:

  • elementNode.attributes(屬性返回包含被選節點屬性的 NamedNodeMap

  • elementNode.getAttribute(name)(方法經過名稱獲取屬性的值)

  • elementNode.setAttribute(name, value)(方法建立或改變某個新屬性)

  • elementNode.removeAttribute(name)(方法經過名稱刪除屬性的值)


attributes.value

設置或返回屬性的值

<input id="input" value="value"/>
        <script type="text/javascript">
            var i = document.getElementById("input");
            console.log(i.attributes.value.value)
        </script>

這段代碼首先得到inputHTML元素,而後調用attributes返回NameNodeMap屬性節點集合,裏面的屬性以鍵值對方式存在,以後調用value屬性的屬性值。


attribute.setNamedItem()

setNamedItem() 方法向 nodeMap 添加指定的節點。
若是此節點已存在,則將替換該節點,並返回被替換的節點,不然返回值是 null

var i = document.getElementById("input");
            var c = document.createAttribute("class");
            c.nodeValue = "cla";
            i.attributes.setNamedItem(c)
  • 建立屬性節點,設置節點值,添加到元素節點下,而後設置屬性節點,這裏用的是attributes方法,即namednodemap.removeNamedItem(nodename)

  • 添加屬性節點也可使用element.setAttributeNode(attributenode)方法;


關於更多:HTML DOM Attribute 對象,其中提到了不要在屬性節點上使用節點對象的屬性和方法

經常使用方法:HTML DOM


關於事件一章我會另開一篇博文繼續研究

相關文章
相關標籤/搜索