JavaScript學習 7、DOM

 DOM(文檔對象模型)是針對HTML和XML文檔的一個API。DOM描繪了一個層次化的節點樹。容許開發人員添加、移除、修改頁面的某一部分。javascript

節點層次

 文檔節點是每一個文檔的根節點,文檔元素是文檔的最外層元素,文檔中其餘說有的元素都包含在文檔元素中,每一個文檔只能有一個文檔元素,在HTML 中,文檔元素始終是<html> 元素,在XML 中沒有預約義的元素,所以任何元素均可能成爲文檔元素。html

每一段標記均可以經過樹中的一個節點來表示:HTML 元素經過元素節點表示,特性(attribute)經過特性節點表示,文檔類型經過文檔類型節點表示,而註釋則經過註釋節點表示,總共有12 種節點類型。java

 1.Node類型node

DOM1 級定義了一個Node 接口,該接口將由DOM中全部節點類型實現。這個Node在JavaScript中是做爲Node 類型實現的;JavaScript 中全部節點都繼承自Node 類型,所以全部節點類型都共享相同的基本屬性和方法。編程

屬性數組

每一個節點都有一個nodeType 屬性,用於代表節點的類型。節點類型由在Node類型中定義的下列 12 個數值常量來表示,任何節點類型必居其一。瀏覽器

  • Node.ELEMENT_NODE(1)
  • Node.ATTRIBUTE_NODE(2)
  • Node.TEXT_NODE(3);
  • Node.CDATA_SECTION_NODE(4)
  • Node.ENTITY_REFERENCE_NODE(5)
  • Node.ENTITY_NODE(6)
  • Node.PROCESSING_INSTRUCTION_NODE(7)
  • Node.COMMENT_NODE(8)
  • Node.DOCUMENT_NODE(9)
  • Node.DOCUMENT_TYPE_NODE(10)
  • Node.DOCUMENT_FRAGMENT_NODE(11)
  • Node.NOTATION_NODE(12)

 能夠用節點的nodeType屬性和上面的常量比較,若是相等,則說明節點是 該類型的元素。因爲IE沒有公開Node類型的構造函數,因此爲了確保跨瀏覽器兼容,最好仍是將nodeType屬性與數字值進行比較。緩存

if(someNode.nodeType == 1){  //Node.ELEMENT_NODE
    alert("Node is an element");
}

 

 可使用nodeName 和 nodeValue 者兩個屬性來了解節點的具體信息,對於元素節點,nodeName中保存的始終都是元素的表簽名,而nodeValue 則始終爲null。app

每個節點都保存者一個childNodes 屬性,其中保存着一個NodeList對象。NodeList是一種相似於數組的對象,用於保存一組有序的節點。NodeList 對象的獨特之處在於,它其實是基於DOM結構動態執行查詢的結果,所以DOM結構的變化可以自動反應在NodeList 對象中。dom

可使用方括號或者item方法來訪問NodeList中的對象。

var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

 

可使用Array.prototype.slice()方法將NodeList轉換成普通的ArrayList對象。

var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0);

 

每一個節點還有 prentNode、previousSibling、nextSibling、firstChild、lastChild等屬性。顧名思義,再也不一一介紹。

方法

節點的關係指針都是隻讀的,因此DOM提供了一些操做節點的方法。其中最經常使用的是appendChild(),用於向childNodes 列表的末尾添加一個節點。返回新增的節點。

使用insertBefore()方法能夠把節點方法childNodes 列表中某個特定的位置上。接收兩個參數:要插入的節點和做爲參照的節點。插入節點後,被插入的節點會變成參照節點的前一個兄弟節點(previousSibling),同時被方法返回。若是參照節點是null, 則insertBefore() 與 appendChild() 執行相同的操做。

 replaceChild()方法接收兩個參數:要插入的節點和要替換的節點。要替換的節點將由這個方法返回並從文檔樹中被移除,同時由要插入的節點佔據其位置。

removeChild()方法接收一個參數,即要移除的節點。被移除的節點將成爲方法的返回值。

cloneNode() 用於建立調用這個方法的節點的一個徹底相同的副本。該方法接收一個布爾值參數,表示是否執行深複製。

2.Document類型

JavaScript 經過Document 類型表示文檔,在瀏覽器中,document 對象是HTMLDocument的一個實例,表示整個HTML頁面。並且document對象是window對象的一個屬性,所以能夠做爲全局對象來訪問。

document 的 nodeType 爲9, nodeName 爲「#document」,nodeValue 爲null parentNode 爲null,ownerDocument爲null。

Document 節點的子節點能夠是DocumentType、Element、ProcessingInstruction 或 Comment,但仍是有兩個內置的訪問其子節點的快捷方式。

第一個就是documentElement 屬性,該屬性始終指向 HTML 頁面中的<html> 元素。另外一個就是body 屬性,直接指向<body> 元素。

document 對象有一些標準的Document 對象所沒有的屬性。這些屬性提供了document 對象所表現的頁面的一些信息。

第一個屬性是 title,包含者<title> 元素中的文本----顯示在瀏覽器窗口的標題欄或標籤頁上。經過這個屬性能夠取得當前頁面的標題,也能夠修改當前頁面的標題並反應在瀏覽器的標題欄中。

URL屬性中包含頁面完整的URL,domain 屬性中包含頁面的域名,而referrer 屬性中則保存着聯街道當前頁面的哪一個頁面的URL。在沒有來源頁面的狀況下,referrer 屬性中可能會包含空字符串。全部這些信息都存在於請求的HTTP 頭部,只不過是經過這些屬性讓咱們可以在JavaScript中訪問他們而已。

document提供了兩個方法用於查找某個或某組元素的引用:getElementById() 和 getElementsByTagName()。

getElementsByTagName() 函數返回的是包含0或多個元素的 NodeList。在HTML中,這個方法會返回一個HTMLCollection 對象,做爲一個動態集合,該對象與NodeList 很是相似。

getElementsByName() 方法是HTMLDocument 特有的方法,返回帶有給定name 特性的全部元素。

document對象還有一些特殊的集合,這些集合都是HTMLCollection對象,爲訪問文檔經常使用部分提供了快捷方式。

  • document.anchors, 包含文檔中全部帶name特性的<a> 元素。
  • document.forms,包含文檔中全部的<form> 元素。與  document.getElementsByTagName("form") 獲得的結果相同。
  • document.images,包含文檔中全部的<img> 元素,與 document.getElementsByTagName("img") 獲得的結果相同。
  • document.links,包含文檔中全部帶href特性的<a>元素。

3.Element類型

  • nodeType 值爲 1
  • nodeName 值爲元素表簽名
  • nodeValue 值爲 null
  • parentNode 多是 Document或 Element
  • 其子節點多是 Element、Text、Comment、ProcessingInstruction、CDATASection 或 EntityReference。

要訪問元素的標籤名,可使用nodeName屬性,也可使用tagName 屬性;這兩個屬性會返回相同的值。

全部的HTML元素都由HTMLElement 類型表示,不是直接經過這個類型也是經過它的子類型來表示。HTMLElement 類型直接繼承自Element 並添加了一些屬性。添加的這些屬性分別對應於每一個HTML都存在的下列標準特性:

  • id,元素在文檔中的惟一標識符
  • title,有關元素的附加說明信息,通常經過工具提示條顯示出來
  • lang,元素內容的語言代碼,不多使用
  • dir,語言的方向,值爲「ltr」(left-to-right,從左向右)或「rtl」(right-to-left,從右向左),也甚少使用。
  • className,與元素class特性對應,即爲元素制定的CSS 類。沒有將這個屬性命名爲class,是由於class 是ECMAScript的保留字。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
    <div id="myDiv" class="bd" title="Body text" lang="en" dir="rtl">good morning</div>
        <script type="text/javascript">
        var div = document.getElementById("myDiv");
        alert("id=" + div.id + ", class=" + div.className + ", title=" + div.title + ", lang=" + div.title + ", dir=" + div.dir);  //id=myDiv, class=bd, title=Body text, lang=Body text, dir=rtl
        </script>
    </body>
</html>

 getAttribute()方法也能夠取得屬性內容,也能夠取得自定義的特性。參數傳遞屬性名稱,不去分大小寫。

在經過JavaScript 以編程方式操做DOM 時,開發人員常常不使用getAttribute(),而是隻使用對象的屬性。只有在取得自定義特性值的狀況下,纔會使用getAttribute() 方法。

setAttribute() 方法能夠爲對象設置屬性,也能夠操做自定義特性,經過這個方法設置的特性名會被統一轉換成小寫形式。

removeAttribute() 方法用於完全刪除元素的特性。調用這個方法不只會清除特性的值,並且也會從元素中徹底刪除特性。

Element 類型是使用attributes 屬性的惟一一個DOM 節點類型。attributes 屬性中包含一個NamedNodeMap,是一個動態集合。元素的每個特性都是一個Attr節點表示,每一個節點都保存在NamedNodeMap對象中。NamedNodeMap對象擁有下列方法:

  • getNamedItem(name):返回nodeName屬性等於name的節點;
  • removeNamedItem(name):從列表中移除nodeName屬性等於name的節點;
  • setNamedItem(node):向列表中添加節點,以節點的nodeName 屬性爲索引;
  • item(pos):返回位於數字pos位置處的節點。

attributes屬性中包含一系列節點,每一個節點的nodeName 就是特性的名稱,而節點的 nodeValue 就是特性的值。要取得元素的id特性,可使用如下代碼。

var id = element.attributes.getNamedItem("id").nodeValue;

var id = element.attributes["id"].nodeValue;

element.attributes["id"].nodeValue = "newId";

 

 通常來講,由於attributes 的方法不夠方便,所以開發人員更多的會使用 getAttribute()、setAttributes()、removeAttributes()方法。

建立元素,使用document.creatElement()能夠建立新元素,這個方法只接收一個參數,即要建立元素的標籤名,

var div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";

 4.Text類型

  • nodeType 值爲3;
  • nodeName 值爲 「#text」;
  • nodeValue 值爲節點所包含的文本;
  • parentNode是一個Element;
  • 不支持(沒有)子節點。

能夠經過nodeValue 屬性或者 data 屬性來訪問Text 節點中包含的文本,這兩個屬性中包含的值相同。對nodeValue的修改也會經過data反映出來,反之亦然。

可使用下列方法來操做節點中的文本。

  • appendData(text):將text添加到節點的末尾。
  • deleteData(offset, count):從offset指定的位置開始刪除count個字符。
  • insertData(offset, text):在offset 指定的的位置插入text。
  • replaceData(offset, count, text):用text替換從offset 指定的位置開始到 offset+count 爲止處的文本。
  • splitText(offset):從offset 指定的位置將當前文本節點分紅了兩個文本節點。
  • substringData(offset, count):提取從offset 指定的位置開始到 offset+count 爲止處的字符串。

文本節點還有一個length 屬性,保存着節點中字符的數目。

建立文本節點,可使用 document.createTextNode()建立新文本節點,這個方法接受一個參數----要插入的文本。

 

DOM操做技術

 操做表格

<table> 元素是 HTML中最複雜的結構之一,要想建立表格,通常都必須設計表示表格行、單元格、表頭等方面的標籤。因爲涉及的標籤多,所以使用核心的DOM方法建立和修改表格每每都免不了要編寫大量的代碼。爲了方便構建表格,HTML DOM 還爲<table>、<tbody>和<tr>元素添加了一些屬性和方法。

爲<table>元素添加的屬性和方法:

  • caption:保存着對<caption>元素的指針;
  • tBodies:是一個<tbody> 元素的HTMLCollection。
  • tFoot:保存着對 <tfoot>元素的指針;
  • tHead:保存着對<thead>元素的指針;
  • rows:是一個表格中全部行的HTMLCollection;
  • createTHead():建立<thead> 元素,將其放到表格中,返回引用;
  • createTFoot():建立<tfoot> 元素,將其放到表格中,返回引用。
  • createCaption():建立<caption> 元素,將其放到表格中,返回引用。
  • deleteTHead():刪除<thead>元素。
  • deleteTFoot():刪除<tfoot>元素。
  • deleteCaption():刪除<caption> 元素。
  • deleteRow(pos):刪除指定位置的行。
  • insertRow(pos):向rows集合中的制定位置插入一行。

爲<tbody> 元素添加的屬性和方法:

  • rows:保存着<tbody>元素中的行的HTMLCollection。
  • deleteRow(pos):刪除指定位置的行。
  • insertRow(pos):向rows集合中的制定位置插入一行,返回對新插入行的引用。

爲<tr>元素添加的屬性和方法:

  • cells:保存着<tr>元素中單元格的HTMLCollection。
  • deleteCell(pos):刪除制定位置的單元格。
  • insertCell(pos):向cells集合中的指定位置插入一個單元格返回對新單元格的引用。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
    
        <script type="text/javascript">
        var table = document.createElement("table");
        table.border = 1;
        table.width = "100%";

        //create tbody
        var tbody = document.createElement("tbody");
        table.appendChild(tbody);

        //first row
        tbody.insertRow(0);
        tbody.rows[0].insertCell(0);
        tbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1, 1"));
        tbody.rows[0].insertCell(1);
        tbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 1, 2"));

        //second row
        tbody.insertRow(1);
        tbody.rows[1].insertCell(0);
        tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2, 1"));
        tbody.rows[1].insertCell(1);
        tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2, 2"));

        document.body.appendChild(table);
        
        </script>
    </body>
</html>

 

NodeList

NodeList、NamedNodeMap 和 HTMLCollection 三個集合都是動態的集合,每當文檔結構發生變化是,他們都會更新。所以他們始終都會保存着最新、最準確的信息。從本質上說,全部NodeList對象都是在訪問DOM文檔時實時運行查詢。

var divs = document.getElementsByTegName("div"), i, div;

for(i = 0; i < divs.length; i++){
    div = document.createElement("div");
    document.body.appendChild(div);
}

 

因爲divs是動態集合,因此上面代碼會致使無限循環,解決方法是把divs.length保存到另外一個變量中進行緩存。

通常來講,應該儘可能減小訪問NodeList的次數。

小結

DOM是語言中立的 API,用於訪問HTML 和XML 文檔。DOM1級將HTML和XML 文檔形象地看作一個層次化的節點樹,可使用JavaScript來操做這個節點樹,進而改變底層文檔的外觀和結構。

  • 最基本的節點類型是Node, 用於抽象地表示文檔中一個獨立的部分;全部其餘類型都繼承自Node。
  • Document 類型表示整個文檔,是一組分層節點的根節點,在JavaScript 中, document對象是Document的一個實例。使用document 對象,有不少中方式能夠查詢和取得節點。
  • Element 節點表示文檔中全部HTML 或 XML 元素,能夠用來操做這些元素的內容和特性。
  • 另外還有一些節點類型,分別表示文本內容、註釋、文檔類型、CDATA區域和文檔片斷。
相關文章
相關標籤/搜索