JavaScript中對(duì)DOM節(jié)點(diǎn)的訪問(wèn)、創(chuàng)建、修改、刪除
DOM
DOM就是Document object Model的縮寫(xiě)。文檔對(duì)象模型是把XML或HTML以樹(shù)節(jié)點(diǎn)為表現(xiàn)形式的文檔。用DOM方法和屬性,你可以訪問(wèn),修改,刪除頁(yè)面上任意一個(gè)元素,也是可以添加一個(gè)元素。DOM是獨(dú)立于語(yǔ)言的API,可以被任意語(yǔ)言所實(shí)現(xiàn),當(dāng)然也包括了Javascript
看看下面的一個(gè)文本。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>My page</title> </head> <body> <p class="opener">first paragraph</p> <p><em>second</em> paragraph</p> <p id="closer">final</p> </body> </html>
我們來(lái)看看第二段
<p><em>second</em> paragraph</p>
可以看到這是個(gè)p標(biāo)簽。它被包含在body標(biāo)簽中。所以說(shuō)body是p的父節(jié)點(diǎn),p是子節(jié)點(diǎn)。第一段和第三段也是body的子節(jié)點(diǎn)。它們都是第二段的兄弟節(jié)點(diǎn)。這個(gè)em標(biāo)簽是第二段p的子節(jié)點(diǎn)。因此p就是它的父節(jié)點(diǎn)。父子節(jié)點(diǎn)關(guān)系能描繪出像樹(shù)一樣的關(guān)系。所以叫做DOM結(jié)構(gòu)樹(shù)(DOM tree).
Core DOM 和 HTML DOM
我們已經(jīng)知道DOM可以描繪出HTML和XML文檔。事實(shí)上HTML文檔就是XML文檔,只不過(guò)更為規(guī)范些。因此作為DOM Level 1的一部分,Core DOM規(guī)范適用于所有XML文檔以及HTML DOM規(guī)范擴(kuò)展了Core DOM.當(dāng)然HTML DOM不能適用于所有的XML文檔,僅僅適用于HTML文檔。讓我們來(lái)看看Core DOM和HTML DOM的構(gòu)造器。
構(gòu)造器關(guān)系
訪問(wèn)DOM節(jié)點(diǎn)
當(dāng)要驗(yàn)證表單或者更換圖片之前,我們要知道怎么樣訪問(wèn)元素(element.)。有很多方法獲取元素。
Document節(jié)點(diǎn)
通過(guò)document我們可以訪問(wèn)當(dāng)前的文檔。我們可以通過(guò)firebugs(火狐插件),來(lái)查看document的屬性和方法。
所有的節(jié)點(diǎn)都有nodeType,nodeName,nodeValue的屬性。我們來(lái)看看document的nodeType是什么
document.nodeType;//9
一共有12節(jié)點(diǎn)類型。document是9。常用的是元素(element:1),屬性(attribute:2),文本(text:3)。
節(jié)點(diǎn)還有名稱。對(duì)于HTML標(biāo)簽。節(jié)點(diǎn)名稱就是標(biāo)簽名稱。文本節(jié)點(diǎn)(text)的名字是#text.文檔節(jié)點(diǎn)(document)的名字是#document.
節(jié)點(diǎn)也有值。對(duì)于文本節(jié)點(diǎn),值就是文本。document的值為null
documentElement
XML都會(huì)有個(gè)ROOT節(jié)點(diǎn)來(lái)包文檔包含起來(lái)。對(duì)于HTML文檔。ROOT節(jié)點(diǎn)就是html標(biāo)簽。訪問(wèn)root節(jié)點(diǎn)??梢杂胐ocumentElement的屬性。
document.documentElement;//<html> document.documentElement.nodeType;//1 document.documentElement.nodeName;//HTML document.documentElement.tagName;//對(duì)于element,nodeName和tagName相同
Child Nodes
為了確定是否包含子節(jié)點(diǎn)我們可以用如下方法
document.documentElement.hasChildNodes();//true
HTML有兩個(gè)子節(jié)點(diǎn)。
document.documentElement.childNodes.length;//2 document.documentElement.childNodes[0];//<head> document.documentElement.childNodes[1];//<body>
也可以通過(guò)子節(jié)點(diǎn)訪問(wèn)父節(jié)點(diǎn)
document.documentElement.childNodes[1].parentNode;//<html>
我們把body的引用賦值變量
var bd = document.documentElement.childNodes[1]; bd.childNodes.length;//9
讓我們看看body的結(jié)構(gòu)
<body> <p class="opener">first paragraph</p> <p><em>second</em> paragraph</p> <p id="closer">final</p> <!-- and that's about it --> </body>
為什么子節(jié)點(diǎn)個(gè)數(shù)為9個(gè)呢。
首先是4個(gè)P還有一個(gè)注釋一共4個(gè)。
4個(gè)節(jié)點(diǎn)包含了3個(gè)空白的節(jié)點(diǎn)。這就7個(gè)。
第8個(gè)在body和第一個(gè)p之間的空白節(jié)點(diǎn)。
第9個(gè)就是在注釋與</body>之間的空白節(jié)點(diǎn)。
一共9個(gè)節(jié)點(diǎn)。
屬性
因?yàn)榈谝还?jié)點(diǎn)是空白節(jié)點(diǎn),所以第二個(gè)節(jié)點(diǎn)才是第一個(gè)p標(biāo)簽。
bd.childNodes[1];// <p class="opener">
可以查看它是否有屬性
bd.childNodes[1].hasAttributes();//true
也可以查看attributes的個(gè)數(shù)
bd.childNodes[1].attributes.length;//1 //可以用index和名字來(lái)訪問(wèn)屬性,也可以用getAttribute方法。 bd.childNodes[1].attributes[0].nodeName;//class bd.childNodes[1].attributes[0].nodeValue;//opener bd.childNodes[1].attributes['class'].nodeValue;//opener bd.childNodes[1].getAttribute('class');//opener
訪問(wèn)標(biāo)簽里的內(nèi)容
讓我們看看第一個(gè)標(biāo)簽p
你可以用textContent屬性來(lái)訪問(wèn)。要注意的是,在IE瀏覽器中并不存在textContent,請(qǐng)用innerText來(lái)替換,結(jié)果都是一樣的。
bg.childNodes[1].textContent;// "first paragraph"
還有一個(gè)屬性是innerHTML.這并不是DOM的規(guī)范。但是主流瀏覽器都支持這個(gè)屬性。它返回的是HTML代碼。
bg.childNodes[1].innerHTML;// "first paragraph"
第一段沒(méi)有html代碼,所以結(jié)果和textContent(IE里是innerText)是一樣的。來(lái)看下第二段包含HTML代碼的標(biāo)簽
bd.childNodes[3].innerHTML;//"<em>second</em> paragraph" bd.childNodes[3].textContent;//second paragraph
另一種方法可以獲取文本節(jié)點(diǎn),然后再取nodeValue屬性,代碼如下
bd.childNodes[1].childNodes.length;//1 子節(jié)點(diǎn)個(gè)數(shù) bd.childNodes[1].childNodes[0].nodeName;// 節(jié)點(diǎn)名稱 #text bd.childNodes[1].childNodes[0].nodeValue;//節(jié)點(diǎn)值 first paragraph
快速訪問(wèn)DOM
通過(guò)childNodes,parentNode,nodeName,nodeValue以及attributes,可以訪問(wèn)文檔任意的節(jié)點(diǎn)了。但是在實(shí)際運(yùn)用過(guò)程中,文本節(jié)點(diǎn)是比較討厭的。如果文本改變了,有可能就影響腳本了。還有如果DOM樹(shù)足夠的深入,那么訪問(wèn)起來(lái)的確有些不方便。幸好我們可以用更為方便的方法來(lái)訪問(wèn)節(jié)點(diǎn)。這些方法是
getElementsByTagName() getElementsByName() getElementById()
首先說(shuō)下getElementsByTagName()
通過(guò)一個(gè)標(biāo)簽名稱(tag name)來(lái)獲取一個(gè)html元素的集合。例子如下
document.getElementsByTagName('p').length;//3
因?yàn)榉祷氐氖莻€(gè)集合,我們可以用過(guò)數(shù)組下標(biāo)的形式來(lái)訪問(wèn)或者通過(guò)item方法。比較一下還是推薦用數(shù)組的訪問(wèn)方法。更簡(jiǎn)單一些。
document.getElementsByTagName('p')[0];// <p class="opener"> document.getElementsByTagName('p').item(0);//和上面的結(jié)果一樣 document.getElementsByTagName('p')[0].innerHTML;//first paragraph
訪問(wèn)元素的屬性,可以用attributes集合。但是更簡(jiǎn)單的方法是直接作為一個(gè)屬性來(lái)訪問(wèn)就行??磦€(gè)例子
document.getElementsByTagName('p')[2].id;//closer
要注意的是,class屬性不能正常的使用。。要用className。因?yàn)閏lass在javascript規(guī)范中是保留字。
document.getElementsByTagName('p')[0].className;//opener
我們可以用如下方法訪問(wèn)頁(yè)面所有元素
<span style="color: #ff0000;">document.getElementsByTagName('*').length;//9</span>
注意:在IE早期的版本不支持上述方法??梢杂胐ocument.all來(lái)取代。IE7已經(jīng)支持了,但是返回的是所有節(jié)點(diǎn)(node),而不僅僅是元素節(jié)點(diǎn)(element nodes)。
Siblings, Body, First, Last Child
nextSibling和previousSibling是兩個(gè)比較方便訪問(wèn)DOM的方法。用來(lái)訪問(wèn)相鄰的節(jié)點(diǎn)的。例子如下
var para = document.getElementById('closer') para.nextSibling;//"\n" para.previousSibling;//"\n" para.previousSibling.previousSibling;//<p> para.previousSibling.previousSibling.previousSibling;//"\n" para.previousSibling.previousSibling.nextSibling.nextSibling;// <p id="closer">
body 用來(lái)訪問(wèn)body元素的。
document.body;//<body>
firstChild 和lastChild 。firstChild是和childNodes[0]一樣.lastChild和 childNodes[childNodes.length - 1]一樣。
遍歷DOM
通過(guò)以上的學(xué)習(xí),我們可以寫(xiě)個(gè)函數(shù),用來(lái)遍歷DOM
function walkDOM(n) { do { alert(n); if (n.hasChildNodes()) { walkDOM(n.firstChild) } } while (n = n.nextSibling) } walkDOM(document.body);//測(cè)試
修改節(jié)點(diǎn)
下面來(lái)看看DOM節(jié)點(diǎn)的修改。
先獲取要改變的節(jié)點(diǎn)。
var my = document.getElementById('closer');
非常容易更改這個(gè)元素的屬性。我們可以更改innerHTML.
my.innerHTML = 'final';//final
因?yàn)閕nnerHTML可以寫(xiě)入html,所以我們來(lái)修改html。
my.innerHTML = '<em>my</em> final';//<em>my</em> fnal
em標(biāo)簽已經(jīng)成為dom樹(shù)的一部分了。我們可以測(cè)試一下
my.firstChild;//<em> my.firstChild.firstChild;//my
我們也可以通過(guò)nodeValue來(lái)改變值。
my.firstChild.firstChild.nodeValue = 'your';//your
修改樣式
大部分修改節(jié)點(diǎn)可能都是修改樣式。元素節(jié)點(diǎn)有style屬性用來(lái)修改樣式。style的屬性和css屬性是一一對(duì)應(yīng)的。如下代碼
my.style.border = "1px solid red";
CSS屬性很多都有破折號(hào)("-"),如padding-top,這在javascript中是不合法的。這樣的話一定要省略波折號(hào)并把第二個(gè)詞的開(kāi)頭字母大寫(xiě),規(guī)范如下。 margin-left變?yōu)閙arginLeft。依此類推
my.style.fontWeight = 'bold';
我們還可以修改其他的屬性,無(wú)論這些屬性是否被初始化。
my.align = "right"; my.name = 'myname'; my.id = 'further'; my;//<p id="further" align="right" style="border: 1px solid red; font-weight: bold;">
創(chuàng)建節(jié)點(diǎn)
為了創(chuàng)建一個(gè)新的節(jié)點(diǎn),可以使用createElement和createTextNode.如果新建完成,可以用appendChild()把節(jié)點(diǎn)添加到DOM樹(shù)中。
創(chuàng)建一個(gè)元素P,并把設(shè)置innerHTML屬性
var myp = document.createElement('p'); myp.innerHTML = 'yet another';
元素P建完成了,就可以隨意修改添加屬性了
myp.style.border = '2px dotted blue'
接下來(lái)可以用appendChild把新的節(jié)點(diǎn)添加到DOM樹(shù)中的。
document.body.appendChild(myp)
使用DOM的方法
用innerHTML方法的確很簡(jiǎn)單,我們可以用純的dom方法來(lái)實(shí)現(xiàn)上面的功能。
- 新建一個(gè)文本節(jié)點(diǎn)(yet another)
- 新建一個(gè)段落
- 把文本節(jié)點(diǎn)添加到段落中。
- 把段落添加到body中
// 創(chuàng)建p var myp = document.createElement('p'); // 創(chuàng)建一個(gè)文本節(jié)點(diǎn) var myt = document.createTextNode('one more paragraph') myp.appendChild(myt); // 創(chuàng)建一個(gè)STRONG元素 var str = document.createElement('strong'); str.appendChild(document.createTextNode('bold')); // 把STRONG元素添加到P中 myp.appendChild(str); // 把P元素添加到BODY中 document.body.appendChild(myp); //結(jié)果<p>one more paragraph<strong>bold</strong></p> cloneNode()
另一種新建節(jié)點(diǎn)的方法是,我們可以用cloneNode來(lái)復(fù)制一個(gè)節(jié)點(diǎn)。cloneNode()可以傳入一個(gè)boolean參數(shù)。如果為true就是深度復(fù)制,包括他的子節(jié)點(diǎn),false,僅僅復(fù)制自己。
首先獲取要復(fù)制的元素。
var el = document.getElementsByTagName('p')[1];//<p><em>second</em> paragraph</p>
先不用深度復(fù)制。
document.body.appendChild(el.cloneNode(false))
我們發(fā)現(xiàn)頁(yè)面并沒(méi)有變化,因?yàn)閮H僅復(fù)制的是元素p。和下面的效果一樣。
document.body.appendChild(document.createElement('p'));
如果用深度復(fù)制,包括p下面所有的子節(jié)點(diǎn)都會(huì)被復(fù)制。當(dāng)然包括文本節(jié)點(diǎn)和EM元素。
document.body.appendChild(el.cloneNode(true))
insertBefore()
用appendChild,就是把元素添加到最后。而insertBefore方法可以更精確控制插入元素的位置。
elementNode.insertBefore(new_node,existing_node)
實(shí)例
document.body.insertBefore( document.createTextNode('boo!'), document.body.firstChild );
意思就是新建一個(gè)文本節(jié)點(diǎn),把它作為body元素的第一個(gè)節(jié)點(diǎn)。
刪除節(jié)點(diǎn)
要從DOM樹(shù)刪除一個(gè)節(jié)點(diǎn),我們可以使用removeChild().我們來(lái)看看要操作的HTML
<body> <p class="opener">first paragraph</p> <p><em>second</em> paragraph</p> <p id="closer">final</p> <!-- and that's about it --> </body>
來(lái)看看下面代碼,刪除第二段
var myp = document.getElementsByTagName('p')[1]; var removed = document.body.removeChild(myp);
removed節(jié)點(diǎn)就是刪除的節(jié)點(diǎn)。以后還可以用這刪除的節(jié)點(diǎn)。
我們也可以用replaceChild()方法。這個(gè)方法是刪除一個(gè)節(jié)點(diǎn),并用另一個(gè)節(jié)點(diǎn)替代。當(dāng)執(zhí)行上個(gè)刪除節(jié)點(diǎn)操作之后,結(jié)果如下
<body> <p class="opener">first paragraph</p> <p id="closer">final</p> <!-- and that's about it --> </body>
我們來(lái)看看replaceChild的使用。我們把上一個(gè)刪除節(jié)點(diǎn)來(lái)替代第二個(gè)p
var replaced = document.body.replaceChild(removed, p);
和removeChild返回一樣。replaced就是移除的節(jié)點(diǎn)?,F(xiàn)在結(jié)果為
<body> <p class="opener">first paragraph</p> <p><em>second</em> paragraph</p> <!-- and that's about it --> </body>
- 詳解JS獲取HTML DOM元素的8種方法
- javascript 獲取HTML DOM父、子、臨近節(jié)點(diǎn)
- Js 獲取HTML DOM節(jié)點(diǎn)元素的方法小結(jié)
- 通過(guò)JS動(dòng)態(tài)創(chuàng)建一個(gè)html DOM元素并顯示
- JS添加或刪除HTML dom元素的方法實(shí)例分析
- JS中使用DOM來(lái)控制HTML元素
- JavaScript基于Dom操作實(shí)現(xiàn)查找、修改HTML元素的內(nèi)容及屬性的方法
- JavaScript操作HTML DOM節(jié)點(diǎn)的基礎(chǔ)教程
- JS常見(jiàn)DOM節(jié)點(diǎn)操作示例【創(chuàng)建 ,插入,刪除,復(fù)制,查找】
- 使用js dom和jquery分別實(shí)現(xiàn)簡(jiǎn)單增刪改
- JavaScript DOM元素常見(jiàn)操作詳解【添加、刪除、修改等】
- JavaScript 實(shí)現(xiàn)HTML DOM增刪改查操作的常見(jiàn)方法詳解
相關(guān)文章
Javascript new Date().valueOf()的作用與時(shí)間戳由來(lái)詳解
本篇文章小編為大家介紹,Javascript new Date().valueOf()的作用與時(shí)間戳由來(lái)詳解。需要的朋友參考下2013-04-04在JavaScript中操作時(shí)間之setYear()方法的使用
這篇文章主要介紹了在JavaScript中操作時(shí)間之setYear()方法的使用,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06深入解讀JavaScript中的Iterator和for-of循環(huán)
這篇文章主要介紹了JavaScript中的Iterator和for-of循環(huán),是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-07-07JavaScript中setTimeout和setInterval函數(shù)的傳參及調(diào)用
這篇文章主要介紹了JavaScript中setTimeout和setInterval函數(shù)的傳參及調(diào)用,著兩個(gè)函數(shù)可以把要執(zhí)行的代碼在設(shè)定的一個(gè)時(shí)間點(diǎn)插入js引擎維護(hù)的一個(gè)代碼隊(duì)列中,需要的朋友可以參考下2016-03-03js parsefloat parseint 轉(zhuǎn)換函數(shù)
JavaScript提供了3個(gè)顯式的類型轉(zhuǎn)換函數(shù),分別是eval()、parseInt()和parseFloat()。2010-01-01js setTimeout 常見(jiàn)問(wèn)題小結(jié)
主要包括this指向問(wèn)題、向setTimeout傳入?yún)?shù)等相關(guān)問(wèn)題,下面與大家分享下以上問(wèn)題的解決方法,感興趣的朋友可以參考下2013-08-08