Js雜談-DOM

前言  

對jQuery的依賴。致使js的原生方法的淡忘,若是是封裝本身的庫,那勢必要用到js的許多原生方法。從Jquery強大的dom處理開始,咱們開始回顧javascript那些古老而堅挺的DOM方法。先從0級DOM入手。javascript

1 節點類型

nodeType name
1 element_node
2 attribute_node
3 text_node
4 cdata_section_node
5 entity_reference_node
6 entity_node
7 processing_instruction_node
8 comment_node
9 document_node
10 document_type_node
11 document_fragment_node
12 notation_node

1.1 dom的基本操做

js擁有對dom樹的增刪改查權利,相對應的方法爲css

document.createElement()//建立
fatherNode.appendChild()//添加
fatherNode.replaceChild('newNode','oldNode')//
fatherNode.childNodes[0-n]//
fatherNode.removeChild(node)//

對於childNodes存在包含text節點,註釋節點等。使用時須要注意。添加和替換節點時,不會額外增長text節點。全部操做權利通常都在父節點上。
這裏有一個cloneNode()方法,它有一個參數,true表示深度複製,能夠複製該元素的子元素,false爲淺度複製,只能複製其自己。在IE9如下版本,存在一點問題,即深度複製時,它們是不會爲空白符建立節點的。java

2 元素類型

2.1 文檔元素

Node Typenode

Document  
nodeType 9
nodeName '#document'
nodeValue null
parentNode null
ownerDocument null

 

 

 

 

 

document表示文檔,在瀏覽器中,document對象時HTMLDocument(繼承自Document類型)的一個實例,表示整個頁面。而卻document對象時window對象的一個屬性。web

document有兩個內置屬性
1.documentElement:直接獲取HTML元素.等同於childNodes[0],firstChild
2.doctype:獲取文檔類型節點
其中第一個屬性是全部瀏覽器都支持,第二個屬性:IEn-8將其解析成註釋節點。因此其值爲null
IE9+ FF:將其解析成document的第一個子節點.
chrome safari opera:能夠解析,但不做爲文檔的子節點。

document對象仍是提供了一些標準的Document對象中所沒有的屬性,這些屬性提供了表現的網頁的一些信息。chrome

console.log(document.title);//網頁標題
console.log(document.URL);//路徑
console.log(document.domain);//域名
console.log(document.referrer);//連接到以前那個頁面的url

只有域名能夠設置,相同的域名的網站可使用javascript相互訪問。編程

如下是一個便捷方式。瀏覽器

document.anchors //全部的a標籤
document.applet //全部的applet標籤
document.forms //全部form元素
document.images //包含全部img元素
document.links//全部帶href特性的a標籤

查找元素app

 Document類型爲此提供了兩種方法:getElementById和getElementsByTagNamedom

在IE8及較低版本不區分ID的大小寫。另外IE7及較低版本還爲此方法添加了一個有意思的「怪癖」:name特性於給定ID匹配的表單元素(input,textarea,button,select)也會被該方法返回,若是有哪一個表單元素的name特性等於指定ID,並且該元素在文檔中位於給定ID的元素前面,那麼IE就會返回那個表單元素。可是爲了不IE中存在的這個問題,最好的辦法是不讓表單字段的name特性與其餘元素的ID相同。

此外還有一個方法就是getElementsByTagName,這個方法接受一個參數,即要取得元素的標籤名,而返回的是包含零或多個元素的NodeList,在HTML文檔中,這個方法會返回一個HTMLCollection對象,做爲一個「動態」集合,該對象與nodeList很是相似。這裏HTMLCollection對象還保存一個方法namedItem(),使用這個方法能夠經過方法經過元素的name特性 取得集合中的項,此外HTMLCollection還支持按名稱訪問項,這就爲咱們取得實際想要的元素提供了便利,並且,對命名的項也可使用方括號語法來訪問。

總的來講,對HTMLCollection而言,咱們能夠向方括號中傳入數值或字符串形式的索引值。在後臺,對數值索引就會調用item(),而對字符串索引就會調用namedItem

另外還有一個方法就是getElementByName(),這個方法會返回給定name特性的全部元素,這個方法一般用在radio上。也返回HTMLCollection 

文檔寫入

具體顯示4個方法:

write(),writeln(),open(),close()。其中,write()和writeln()方法都接受一個字符串參數,即要寫入到輸出流的文本,write()會原樣寫入,而writeln()則會在字符串的末尾添加一個換行符(\n),在頁面被加載的過程當中,可使用這兩個方法向頁面中動態地加入內容。

方法open和close分別用於打開和關閉網頁的輸出流,若是是在頁面加載期間使用write()或writeln()方法。

 2.2 標籤元素

Element  
nodeType 1
nodeName 元素的標籤名
nodeValue null
parentNode Element或Document

 

 

 

 

2.2.1 HTML元素

全部HTML元素都由HTMLCollection類型表示。

每個元素節點都存在屬性,那如何獲取它們的屬性,能夠是標準方法:getAttribute(),setAttribute(),removeAttribute()。

Element類型是使用attributes屬性惟一一個DOM節點類型。attributes屬性中包含一個NameNodeMap,與nodelist相似,是一個動態的集合

有兩類特殊的特性,它們雖然有對應的屬性名,但屬性的值與經過getAttribute返回的值並不相同。第一類特性就是style,用於經過css爲元素指定樣式。在經過getAttribute訪問時,返回style特性值中包含的是css文本,而經過屬性來訪問它則會返回一個對象。因爲style屬性是用於以編程方式訪問元素樣式。第二類不同凡響的特性是onclick這樣的事件處理程序。

IE6以及以前版本不支持removeAttribute

2.2.2 attributes屬性

Element類型是使用attributes屬性惟一一個DOM節點類型。attributes屬性中包含一個NamedNodeMap,於NodeList相似,也是一個動態集合,元素的每個特性都由一個Attr節點表示,每一個節點都保存在NamedNodeMap對象中。

API以下:

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

通常來講,因爲前面介紹的attributes的方法不夠方便,所以開發人員更多的會使用getAttribute,setAttribute和removeAttribute

關於attribute,有兩點必要的說明。

  • 針對attributes對象中的特性,不一樣瀏覽器返回的順序不一樣,這些特性在XML或HTML代碼中出現的前後順序,不必定與它們出如今attributes對象中的順序一致。
  • IE7及更早的版本會返回HTML元素中全部可能的特性,包括沒有指定的特性。換句話說,返回100多個特性的狀況會很常見。
  • 針對IE7及更早版本中存在的問題,讓它只返回指定的特性。每一個特性節點都有一個名爲specified的屬性,這個屬性的值若是爲true,則意味着要麼在HTML中指定相應特性,要麼是經過setAttribute方法設置了該特性,在IE中,全部未設置過的特性的該屬性都爲false

2.2.3 建立元素

document.createElement('xx');

接收參數不區分大小寫,而在XML中是區分大小寫的

在新元素上設置特性只是給它們賦予了相應的信息。因爲新元素還沒有被添加到文檔樹中,所以設置這些特性不會影響到瀏覽器的顯示。要把新元素添加到文檔樹,可使用appendChild,insertBefore或replaceChild方法。

一旦將元素添加到文檔樹中,瀏覽器就會當即呈現該元素,此後,對這個元素所做的任何修改都會實時反映在瀏覽器中。

注意:在IE中可使用另外一種方式使用createElement,以下:

var div = document.createElement("<div id='div1' class='class1'></div>")

相似於jQuery的寫法。這種方式有助於避開IE7及更早版本中動態建立元素的某些問題:

  1. 不能設置動態建立iframe元素的name特性
  2. 不能經過表單的reset()方法重設動態建立的input
  3. 動態建立的type特性值爲reset的button元素重設不了表單
  4. 動態建立的一批name相同的單選按鈕彼此毫無關係,沒法實現單選效果。

上述說到這些問題均可以經過createElement()中指定完整的HTML標籤來解決。

2.2.4 元素的子節點

元素能夠有任意數目的子節點和後代節點,由於元素能夠是其餘元素的子節點。元素的childNodes屬性中包含了它的全部子節點。這些子節點多是元素,文本節點,註釋或是處理指令。不一樣的瀏覽器下看待這些節點方面存在顯著的不一樣。舉個例子:

<ul id="myList">
     <li>1</li>
     <li>2</li>
     <li>3</li>   
</ul>

若是是IE來解析這些代碼,那麼ul會有3個子節點,若是是其餘瀏覽器,則會是7個子節點,即3個li節點和4個文本節點

 2.3 文本元素

nodeType 3
nodeName #text
nodeValue 包含的文本內容
parentNode element

能夠經過nodeValue和data屬性來訪問Text節點中包含的文本。這兩個屬性中包含的值相同。API以下:

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

以上的方法主要是操做文本節點的,而不是文本。默認狀況下,每一個能夠包含內容的元素最多隻能有一個文本節點。並且必須確實有內容存在。

2.3.1 建立文本節點

document.createTextNode()

這個方法接收一個參數-即要插入節點的文本,與設置已有文本節點的值同樣。

若是兩個文本節點是相鄰的同胞節點,那麼這兩個節點中的文本就會連起來顯示,中間不會有空格。

2.3.2 規範化文本節點

DOM文檔中存在相鄰的同胞文本節點很容易致使混亂,由於分不清哪一個文本節點表示哪一個字符串。在一個包含兩個或者多個文本節點的父元素上調用normalize()方法,則將全部文本節點合併成一個節點,結果節點的nodevlaue等於將合併前每一個文本節點的nodeValue值拼接起來的值。

2.3.3 分割文本節點

Text類型提供了一個做用與normalize()相反的方法:splitText(),這個方法會將一個文本節點分紅兩個文本節點:即按照指定的位置分割nodeValue值

 2.4 註釋節點

nodeType 8
nodeName #comment
nodeValue 註釋的內容
parentNode Document或者Element

Comment類型與Text類型繼承自相同的基類,所以它擁有除splitText()以外的全部字符串操做方法。與text類型類似,也能夠經過nodeValue或data屬性來取得註釋的內容,好比訪問一個註釋

var div = document.getElementById('myDiv');
var comment = div.firstChild;
alert(comment.data);

一樣,註釋一樣能夠建立,使用document.createComment()方法,其參數是傳入註釋文本。

 2.5 CDATA元素

nodeType 4
nodeName #cdata-section
nodeValue CDATA區域中的內容
parentNode Document或是element

不支持子節點。CDATA區域出如今XML文檔中,所以多數瀏覽器都會把CDATA區域解析錯誤地解析成Comment或Element。可使用document.createCDataSection()來在XML文件中建立CDATA區域。

 2.6 DocumentType類型

nodeType 10
nodeName doctype
nodeValue null
parentNode Document

DocumentType類型在web瀏覽器中並不常見,僅在FF,safari和opera支持它。在DOM1級中,DocumentType對象不能動態建立,而只能經過解析文檔代碼的方式來建立。支持它的瀏覽器會把DocumentType對象保存在document.doctype中。DOM1級描述了DocumentType對象的3個屬性:name,entities和notations。其中name表示文檔文檔類型的名稱;entities是由文檔類型描述的實體的NamedNodeMap對象;notations是由文檔類型描述的符號的NamedNodeMap對象。一般,瀏覽器中的文檔使用的都是HTML或XHTML文檔類型,於是entities和notations都是空列表(列表的項來自行內文檔類型聲明)。但無論怎麼樣,只有name屬性是有用的,這個屬性中保存的是文檔類型的名稱。

 2.7 文檔片斷

nodeType 11
nodeName #document-fragment
nodeValue null
parentNode null

在全部節點類型中,只有DocumentFragment在文檔中沒有對應的標記。DOM規定文檔片斷是一種'輕量級'的文檔,能夠包含和控制節點,但不會像完整的文檔那樣佔用額外的資源。雖然不能把聞到那股片斷直接添加到文檔中,可是能夠將它做爲一個倉庫來使用。便可以在裏面保存未來可能會添加到文檔中的節點。要建立文檔片斷。可使用以下方法:

document.createDocumentFragment()

文檔片斷繼承了Node的全部方法,一般用於執行那些針對文檔的DOM操做。若是將文檔中節點添加到文檔片斷中,就從文檔樹中移除該節點。

 2.8 屬性類型

nodeType 2
nodeName 特性的name
nodeValue 特性的值
parentNode null

儘管它們也是節點,但特性卻不被認爲是DOM文檔樹的一部分。這個Attr對象有3個屬性:name,value和specified,其中specified是一個布爾值,用以區別特性是在代碼中指定的。

3 DOM部分操做技術

3.1 動態腳本

目的:使用script元素能夠像頁面中插入javascript代碼的方式

  1. 經過其src特性包含外部文件
  2. 就是用這個元素來包含代碼

3.2 動態樣式

所謂動態樣式是指樣式在頁面加載時不存在的樣式;動態樣式是在頁面加載完成後動態添加到頁面中的。加載外部樣式文件的過程是異步的,也就是說加載樣式與執行javascript代碼的過程沒有固定的次序。通常來講,知不知道樣式已經加載完成並不重要。

3.3 操做表格

DOM1級提供了一些操做表格的API

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) 刪除指定位置的行
tbody-rows 保存着tbody元素中行的HTMLCollection
tbody-deleteRow() 刪除指定位置的行
tbody-insertRow() 向rows集合中的指定位置插入一行,返回對新插入行的引用
tr-cells 保存這tr元素中單元格的HTMLCollection
tr-deleteCell(pos) 刪除指定位置的單元格
tr-insertCell(pos) 向cells集合中的指定位置插入一個單元格,返回對新單元格的引用
   

3.4 關於使用NodeList

理解NodeList及其近親NamedNodeMap和HTMLCollection是從總體上透徹理解DOM的關鍵所在,這三個集合都是「動態的」,換句話說,若是文檔結構發生變化時,它們都會獲得更新,所以,它們始終保存着最新,最準確的信息。從本質來講,全部NodeList對象都是訪問DOM文檔時實時查詢。

相關文章
相關標籤/搜索