JavaScript之DOM基礎

概述

DOM(Document Object Model)文檔對象模型,針對Html和XML的文檔的對象API,是一項 W3C (World Wide Web Consortium) 標準。文檔對象模型(DOM)是中立於平臺和語言的接口,它容許程序和腳本動態地訪問、更新文檔的內容、結構和樣式。本文主要以一些簡單的小例子,簡述前端開發中,DOM的常見內容,僅供學習分享使用,若有不足之處,還請指正。javascript

獲取元素

DOM操做必須等待HTML文檔加載完畢,才能夠訪問。html將標籤節點,稱爲元素,若是存在元素,則返回html的javascript對象;若是不存在,則範圍null。html

經過ID獲取元素

一個頁面每一個標籤元素只能有一個id,表示惟一性。經過getElementById獲取標籤對應的JavaScript對象,建議區分大小寫,以避免瀏覽器之間不兼容。以下所示:前端

 1 var box = document.getElementById('A01');
 2 document.write(box);//返回:[object HTMLDivElement] 
 3 document.write(box.tagName);//獲取標籤名:DIV
 4 alert(box.innerHTML);//以文本形式獲取標籤的子內容
 5 document.write(box.id);//返回元素的惟一ID,如:A01
 6 document.write(box.title);//返回元素的標題屬性
 7 document.write(box.style);//返回元素的樣式對象。輸出:[object MSStyleCSSProperties]
 8 document.write(box.style.color);//返回樣式中設置的顏色屬性,輸出:blue 
 9 document.write(box.class);//class是保留字,不能使用,會報錯,改用以下替代:
10 document.write(box.className);//返回樣式名稱,輸出:box 
11 //自定義屬性,非IE不支持
12 box.innerHTML='玩轉JS DOM';//從新賦值,會覆蓋掉以前的內容

經過tagName獲取元素

一個文檔中,相同標籤的元素能夠有多個,因此經過getElementsByTagName獲取的是對應標籤的數組列表對象,以下所示:java

1 var box=document.getElementsByTagName('li');
2 document.write(box);//返回的是HTML列表數組集合對象,如:[object HTMLCollection] 
3 document.write(box.length);//數組集合的長度,元素個數。從0開始
4 document.write(box.item(0));//返回:[object HTMLLIElement] 
5 document.write(box[0].tagName);//返回對應標籤 LI
6 document.write(box[0].innerHTML);//返回指定位置的純文本內容

獲取body

一個文檔對象,也能夠有多個body,因此經過tagName獲取的也是數組列表對象,經過索引來訪問具體內容。以下所示:node

1 var box =document.getElementsByTagName('body')[0];
2 document.write(box);//返回body對象,輸出:[object HTMLBodyElement] 

經過name獲取元素

經過name獲取元素,即經過元素的name屬性來獲取,且name不是惟一的,因此獲取到的也是數組列表對象,以下所示:數組

1 var box=document.getElementsByName('A');
2 document.write(box);//返回一個數組集合:[object HTMLCollection] 
3 document.write(box[0]);//返回第一個元素:[object HTMLDivElement]
4 document.write(box[0].name);//對於IE,由於name在div中是不合法的屬性,因此在IE:輸出undefined ,其餘則正常。
5 document.write(box[0].getAttribute('name'));//經過此方法在IE中能夠獲取name的值
6 document.write(box[0].getAttribute('style'));//IE中,返回的是:color: blue; 字符串
7 alert(box[0].getAttribute('style'));
8 document.write(box[0].getAttribute('class'));//IE瀏覽器不支持,其餘能夠
9 document.write(box[0].getAttribute('className'));//IE支持,其餘不能夠

設置屬性

當獲取元素後,如何給元素動態的設置屬性呢,能夠經過setAttribute方法來設置,以下所示:瀏覽器

1 box[0].setAttribute('title','玩轉,hexkj');//設置屬性,兩個參數:屬性,屬性值,會覆蓋掉以前的值
2 box[0].setAttribute('align','center');
3 //設置自定義屬性
4 box[0].setAttribute('test','hexkj');//也能夠設置成功
5 box[0].removeAttribute('style');//移除屬性

節點類型

DOM的節點類型,常見的有如下幾種,以下所示:服務器

 

 元素節點

元素節點,即html標籤元素節點,節點類型爲1app

1 var box = document.getElementById('A01');
2 document.write(box.nodeName);//獲取元素的標籤名,和tagName同樣,輸出:DIV
3 document.write(box.nodeType);//獲取元素的節點類型值,輸出:1 
4 document.write(box.nodeValue);//當前節點的value,div爲空,只能獲取當前節點,不能獲取子節點的內容
5 document.write(box.innerHTML);//輸出純文本內容,是一個總體
6 document.write(box.childNodes);//子節點集合。返回:[object NodeList] 
7 document.write(box.childNodes.length);//子節點的長度,輸出:3

文本節點

文本節點,即只有文本內容的節點。dom

1 //[object HTMLUListElement]UL節點 元素節點
2 //[object Text]文本節點 屬性節點
3 for (var i=0;i<box.childNodes.length;i++) {
4     document.writeln(box.childNodes[i].nodeName);
5     document.writeln(box.childNodes[i].nodeType);
6     document.writeln(box.childNodes[i].nodeValue);
7     document.writeln('<br />');
8 }

屬性節點

屬性節點,即標籤元素的屬性,經過attributes來訪問,以下所示:

1 document.write(box.attributes.length);//屬性節點的個數
2 document.write(box.attributes[0].nodeType);//屬性類型 ,輸出:2
3 document.write(box.attributes[0].nodeName);//屬性名稱,輸出:title
4 document.write(box.attributes[0].nodeValue);//屬性的值,輸出:我是AO1 
5 document.write(box.attributes['title'].nodeValue);//獲取指定屬性的值,本例輸出:我是AO1 

節點賦值

能夠經過nodeValue和innerHTML進行賦值,可是在設置HTML時,會有差別,以下所示:

1 box.childNodes[0].nodeValue='hello js dom!!!';//能夠設置節點內容
2 box.childNodes[0].nodeValue='hello <strong>js</strong> dom!!!';//可是不能設置html內容:hello <strong>js</strong> dom!!!
3 box.innerHTML='hello <strong>js</strong> dom!!!';//能夠設置html屬性

獲取相關節點

能夠與節點相關的其餘節點,如第一個節點,最後一個節點,父節點,等相關內容,以下所示:

1 var box = document.getElementById('A01');
2 document.write(box.firstChild.nodeValue);//獲取第一個節點
3 document.write(box.lastChild.nodeValue);//獲取最後一個節點
4 document.write(box.ownerDocument);//返回當前的文檔對象,輸出:[object HTMLDocument] 
5 document.write(box.ownerDocument.nodeName);//輸出:#document
6 document.write(box.parentNode);//返回當前節點的父節點,本例輸出:[object HTMLDivElement] 
7 document.write(box.firstChild.nextSibling);//返回第一個節點的下一個同級節點,本例輸出:[object HTMLUListElement] 
8 document.write(box.lastChild.previousSibling);//返回最後一個節點的上一個同級節點,本例輸出:[object HTMLUListElement] 

忽略空白節點

空白節點對於HTML元素節點來講,是沒有太大意義的,要如何去除呢,有兩種方法均可以過濾掉空白節點,以下所示:

 1 //忽略空白字符
 2 var box = document.getElementById('A02');
 3 document.write(box.childNodes.length);//IE瀏覽器,輸出是7,其中包括文本節點
 4 document.write(box.childNodes[0]);//輸出:[object Text]  表名第一個是文本節點,且內容爲空
 5 //如下函數過濾掉空白節點
 6 function filterWhiteNodes(node){
 7     var ret=[];
 8     for (var i=0;i<node.length;i++) {
 9         if (node[i].nodeType==3 && /^\s+$/.test( node[i].nodeValue)) {
10         continue;
11         } else{
12         ret.push(node[i]);
13         }
14     }
15         return ret;
16 }
17 document.write(filterNodes(box.childNodes).length);//輸出:3
18 //輸出空白文本節點
19 function removeWhiteNodes(node){
20     for (var i=0;i<node.length;i++) {
21     if (node[i].nodeType==3 && /^\s+$/.test( node[i].nodeValue)) {
22         node[i].parentNode.removeChild(node[i]);
23     }
24     }
25     return node;
26 }
27 document.write(removeWhiteNodes(box.childNodes).length);//輸出:3
28 document.write(removeWhiteNodes(box.childNodes)[0].nodeName);//輸出P標籤

建立元素節點

經過createElement來建立元素,經過insertBefore來插入指定元素以前,以下所示:

1 var p=document.createElement('P');//建立一個元素
2 var text=document.createTextNode('DDDDD');//建立一個文本節點
3 p.appendChild(text);//將文本節點附加一個子元素節點
4 box.appendChild(p);//將p元素節點,添加到box後面
5 box.insertBefore(p,box.childNodes[1]);//在第2個節點以前添加節點,其中可能會包括空白文本節點

如何插入到指定元素以後呢,以下所示:

 1 function insertAfter(newElement,targetElement){
 2     //獲得父節點
 3     var parent=targetElement.parentNode;
 4     if(parent.lastChild==targetElement){
 5         //若是當前已是最後一個節點,則直接添加
 6         parent.appendChild(newElement);
 7     }else{
 8         parent.insertBefore(newElement,targetElement.nextSibling);
 9     }
10 }
11 //在A02,SPAN之間,添加標籤
12 insertAfter(p,box);

替換節點

經過replaceChild替換節點,以下所示:

1 var span=document.getElementsByTagName('span')[0];
2 var em=document.createElement('em');
3 span.parentNode.replaceChild(em,span);

克隆節點

經過cloneNode方法克隆節點,有一個參數,true:深度克隆,包括內容 false:淺克隆,只克隆標籤。

1 //cloneChild克隆節點
2 var clone = box.cloneNode(true);//true:深度克隆,包括內容 false:淺克隆,只克隆標籤
3 box.parentNode.appendChild(clone);

刪除節點

經過removeChild來刪除節點

1 box.removeChild(box.firstChild);//刪除第一個節點
2 box.parentNode.removeChild(box);//刪除本身

DOM進階

DOM自己的屬性相關內容,以下所示:

 1 alert(document.nodeType);//輸出9表明文檔根
 2 alert(document.nodeName);//輸出:#document
 3 alert(document.nodeValue);//null
 4 alert(document.firstChild.nodeName);//第一個節點,輸出html
 5 alert(document.firstChild.nodeType);//輸出:10
 6 alert(document.documentElement);//獲取文檔的根元素,輸出:[object HTMLHtmlElement]
 7 alert(document.documentElement.nodeName);//輸出:HTML
 8 alert(document.documentElement.nodeType);//輸出:1
 9 alert(document.body);//獲取body元素,輸出:[object HTMLBodyElement]
10 alert(document.body.nodeType);//輸出:1
11 alert(document.body.nodeName);//輸出:BODY
12 alert(document.doctype);//獲取文檔類型 輸出:[object DocumentType]
13 alert(document.doctype.nodeType);//輸出:10   
16 alert(document.title);//返回文檔的標題
17 alert(document.URL);//返回文檔的URL,必須是從服務器訪問才生效
18 alert(document.referrer);//返回上一個url路徑,即跳轉到當前頁面的url
19 alert(document.domain);//返回當前的域名
20 alert( document.images.length);//返回文檔中圖片的數組

合併節點

經過normalize方法來合併相鄰的文本節點,爲一個節點,以下所示:

1 var box=document.getElementById("A01");
2 //合併相鄰節點
3 var text1=document.createTextNode('Mr.');
4 var text2=document.createTextNode('Hex');
5 box.appendChild(text1);
6 box.appendChild(text2);
7 //alert(box.childNodes.length);//此時會發現A01的子節點數是2
8 box.normalize();//此方法用戶合併相鄰的文本節點爲一個節點
9 alert(box.childNodes.length);//此時會發現A01的子節點數是1

分離節點

經過splitText方法,分離文本節點爲兩個相鄰的節點,以下所示:

1 //分離節點,原始:<div id="A01">Mr.Hex</div>
2 alert(box.firstChild.nodeValue);//輸出Mr.Hex
3 box.firstChild.splitText(3);//分離前三個字符爲一個節點
4 alert(box.firstChild.nodeValue);//輸出Mr.

操做節點內容

1 box.firstChild.deleteData(0,3);//刪除節點中的字符,起始位置,刪除個數
2 box.firstChild.insertData(0,'Hello,');//添加字符,起始位置,添加的字符串
3 box.firstChild.replaceData(0,2,'Miss');//替換字符串 起始位置,替換字符數,要替換的字符
4 alert(box.firstChild.substringData(0,2));//返回截取字符串,起始位置,截取字符個數

註釋節點

註釋節點即文檔中的註釋,以<!-- -->包裹,以下所示:

1 var c = document.getElementsByTagName("!");
2 alert( c.length);//經測試IE11獲取不到,長度爲0

滾動到可見位置

當元素默認看不到時,須要手動滾動條才能夠顯示,能夠經過scrollIntoView默認打開時,滾動到指定位置。以下所示:

1 //瀏覽器文檔呈現模式
2 alert(document.compatMode) ;//是否爲經過標準模式,或混合模式 CSS1Compat
3 //<div id="A03" style="height: 800px;"></div>
4 box.scrollIntoView(true);//將節點設置爲滾動可見節點,即會將滾動調試,滾動到顯示節點的位置上

判斷是否包含元素節點

判斷一個元素是否包含指定元素,經過contains方法來判斷。 以下所示:

 1 var box=document.getElementById("A02");
 2 alert(box.childNodes.length);//會包含空白節點
 3 alert(box.children.length);//不會包含空白節點和註釋,和文本元素,不過children是非標準的
 4 var box=document.getElementById("A01");
 5 var p=box.children[0];
 6 alert(box.contains(p));//返回true,是否包含節點
 7 var box=document.getElementById("A02");
 8 //var t=box.children[0];
 9 alert(box.childNodes.length);//輸出3
10 //alert(box.children.length);//輸出0
11 var t=box.childNodes[1];
12 alert(t.nodeValue);//註釋節點
13 alert(box.contains(t));//檢測不出文本節點

兼容瀏覽器,由於有的瀏覽器不支持contains方法,以下所示:

 1 var box=document.getElementById("A01");
 2 var p=box.children[0];
 3 function contains(refNode,otherNode){
 4     if(typeof refNode.contains !='undefined'){
 5         return refNode.contains(otherNode);
 6     }else if(typeof refNode.compareDocumentPosition !='undefined'){
 7         return refNode.compareDocumentPosition(otherNode)>16;
 8     }else{
 9         //或者判斷otherNode的遞歸判斷父節點是否是refNode
10         var node=otherNode.parentNode;
11         do{
12             if(node==refNode){
13                 return true;
14             }else{
15                 node=otherNode.parentNode;
16             }
17         }while (node!=null)
18     }
19 }
20 alert(contains(box,p));//返回true

innerText和outerText的差別

innerText不會覆蓋掉元素自己,outerText會在賦值時覆蓋掉元素自己,以下所示:

 1 var box=document.getElementById("A01");
 2 alert(box.innerText);//獲取元素包含的文本,不包含html內容,且火狐不兼容
 3 alert(box.textContent);//支持火狐的3.0
 4 box.innerText='<strong>Hex Js</strong>';//賦值的時,會進行轉義輸出
 5 
 6 alert(box.outerText);//獲取內容和innerText同樣
 7 box.outerText='Mr. Hex';//可是賦值時會將元素刪掉
 8 alert(document.getElementById("A01"));//輸出null
 9 
10 alert(box.outerHTML);//獲取內容和innerHTML同樣
11 box.outerHTML='<strong>Hex Js</strong>';//可是賦值時會將元素刪掉
12 alert(document.getElementById("A01"));//輸出null

備註

己亥雜詩(清-龔自珍)

浩蕩離愁白日斜,吟鞭東指即天涯。

落紅不是無情物,化做春泥更護花。

相關文章
相關標籤/搜索