DOM(Document Object Model)文檔對象模型,針對Html和XML的文檔的對象API,是一項 W3C (World Wide Web Consortium) 標準。文檔對象模型(DOM)是中立於平臺和語言的介面,它允許程式和腳本動態地訪問、更新文檔的內容、結構和樣式。本文主要以一... ...
概述
DOM(Document Object Model)文檔對象模型,針對Html和XML的文檔的對象API,是一項 W3C (World Wide Web Consortium) 標準。文檔對象模型(DOM)是中立於平臺和語言的介面,它允許程式和腳本動態地訪問、更新文檔的內容、結構和樣式。本文主要以一些簡單的小例子,簡述前端開發中,DOM的常見內容,僅供學習分享使用,如有不足之處,還請指正。
獲取元素
DOM操作必須等待HTML文檔載入完畢,才可以訪問。html將標簽節點,稱為元素,如果存在元素,則返回html的javascript對象;如果不存在,則範圍null。
通過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獲取的是對應標簽的數組列表對象,如下所示:
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獲取的也是數組列表對象,通過索引來訪問具體內容。如下所示:
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標簽元素節點,節點類型為1
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
文本節點
文本節點,即只有文本內容的節點。
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
備註
己亥雜詩(清-龔自珍)
浩蕩離愁白日斜,吟鞭東指即天涯。
落紅不是無情物,化作春泥更護花。