javascript
JavaScript 第三课 DOM
主要內(nèi)容:
- 節(jié)點(diǎn)
- 5個(gè)常用的DOM方法:
????getElementById、getElementByTagname、getElementByClassName、getAttribute和setAttribute
詳細(xì)內(nèi)容:
1、文檔:DOM中的“D”
? ? 如果沒有document(文檔),DOM也就無從談起。當(dāng)創(chuàng)建了一個(gè)網(wǎng)頁并把它加載到Web瀏覽器中時(shí),DOM就在幕后悄然而生。它把你編寫的網(wǎng)頁文檔轉(zhuǎn)換為一個(gè)文檔對(duì)象。
2、對(duì)象:DOM中的“O”
對(duì)象是一種自足的數(shù)據(jù)集合。與特定某個(gè)對(duì)象相關(guān)聯(lián)的變量成為這個(gè)對(duì)象的屬性;只能通過某個(gè)特定對(duì)象去調(diào)用的函數(shù)稱為這個(gè)對(duì)象的方法。
JavaScript語言中的對(duì)象可以分為三種類型。
用戶定義對(duì)象:由程序員自從創(chuàng)建的對(duì)象。
內(nèi)建對(duì)象:內(nèi)建在JavaScript語言里的對(duì)象,例如Array、Math和Date等。
宿主對(duì)象:由瀏覽器提供的對(duì)象。
3、模型:DOM中的"M"
? ? DOM中的”M“代表著”Model“(模型),但說它代表著”Map“(地圖)也是可以的。但他們都是某種事物的表現(xiàn)形式。就像一個(gè)模型火車代表著一列真正的火車那樣。DOM代表著加載到瀏覽器窗口的當(dāng)前網(wǎng)頁。瀏覽器提供了網(wǎng)頁的地圖(或者說模型),而我們可以通過JavaScript去讀取這張地圖。
? ? 要想從DOM獲得信息,必須先把各種表示和描述文檔的"圖例"弄明白。
? ? DOM把一份文檔表示為一顆樹,這是我們理解和運(yùn)用這一模型的關(guān)鍵。更具體地說,DOM把文檔表示為一顆家譜樹。
? ? 家譜樹本身又是一種模型。家譜樹的典型做法是表示一個(gè)人類家族的譜系,并使用parent(父)、child(子)、sibling(兄弟)等記號(hào)來表明家族成員之間的關(guān)系。
? ? 家譜樹模型本身非常適合用來表示一份用(X)HTML語言編寫出來的文檔。
下面是一份非常基本的網(wǎng)頁,內(nèi)容是一份購(gòu)物清單。
<!DOCTYPE html> <html lang = "en"><head><meta charset = "utf-8"/><title>Shopping list</title></head><body> <h1>What to buy</h1><p title= "a gentle reminder">Don't forget to buy this stuff.</p><ul id = "purchases"><li>a tin of beans</li><li class = "sale">Cheese</li><li class = "sale important">Milk</li></ul></body> </html>我們來分析一下:在DOCTYPE之后,一個(gè)打開了的<html>標(biāo)簽標(biāo)識(shí)了整個(gè)文檔的開始,這個(gè)網(wǎng)頁里的所有其他元素都包含在這個(gè)元素里面,這表示它至少是一個(gè)父親(parent)。又因?yàn)樗衅渌脑囟及谄鋬?nèi)部,所以這個(gè)<html>標(biāo)簽既沒有父親,也沒有兄弟,這個(gè)<html>就是樹根。
? ? 根元素是html,不管從哪個(gè)角度來看,html都是代表整個(gè)文檔。
? ? 接下來深入一層,我們發(fā)現(xiàn)有<head>和<body>兩個(gè)分支。
.....
如果把一個(gè)文檔的各個(gè)元素想象成一顆家譜樹,我們就可以用同樣的數(shù)據(jù)描述DOM,不過,與使用"家譜樹"這個(gè)術(shù)語相比,把文檔稱為"節(jié)點(diǎn)樹"更準(zhǔn)確。
4、節(jié)點(diǎn)
? ? 節(jié)點(diǎn)(node)表示網(wǎng)絡(luò)中的一個(gè)連接點(diǎn)。一個(gè)網(wǎng)絡(luò)就是由一些節(jié)點(diǎn)構(gòu)成的集合。
? ? 原子是現(xiàn)實(shí)世界中的節(jié)點(diǎn)。文檔是由節(jié)點(diǎn)構(gòu)成的集合,只不過此時(shí)的節(jié)點(diǎn)是文檔樹上的樹枝和樹葉而已。
? ? 在DOM里有許多不同類型的節(jié)點(diǎn)。就像原子包含著亞原子顆粒那樣,也有很多類型的DOM節(jié)點(diǎn)包含著其他類型的節(jié)點(diǎn)。先看其中的三種:元素節(jié)點(diǎn)、文本節(jié)點(diǎn)、屬性節(jié)點(diǎn)。
????所謂元素節(jié)點(diǎn):DOM的原子就是元素節(jié)點(diǎn)(element node)。
? ? 在上面那份"購(gòu)物清單"文檔時(shí),我們使用了諸如<body>、<p>和<ul>之類的元素。如果把Web上的文檔比作大廈,元素就是建造這座大廈的磚塊,這些元素在文檔的布局形成了文檔的結(jié)構(gòu)。標(biāo)簽的名字就是元素的名字。文本段落元素的名字是"p",無序清單元素的名字是"ul",列表項(xiàng)的名字是"li"。
? ? 元素可以包含其他元素。在上面那份"購(gòu)物清單"文檔里,所有的列表項(xiàng)元素都包含在一個(gè)無序清單元素的內(nèi)容。
????所謂"文本節(jié)點(diǎn)":在上面那份"購(gòu)物清單"文檔里,<p>元素包含著”Don't forget to buy this stuff.“它是一個(gè)文本節(jié)點(diǎn)。(text node)在XHTML文檔中,文本節(jié)點(diǎn)總是被包含在元素節(jié)點(diǎn)的內(nèi)部。但并非所有的元素節(jié)點(diǎn)都包含有文本節(jié)點(diǎn)。
????所謂"屬性節(jié)點(diǎn)":屬性節(jié)點(diǎn)用來對(duì)元素做出更具體的描述。幾乎所有元素都有一個(gè)title屬性,而我們可以利用這個(gè)屬性對(duì)包含在元素里的東西做出準(zhǔn)確的描述:
? ? <p title = "a gentle reminder">Don't forget to buy this stuff.</p>
CSS
????DOM并不是與網(wǎng)頁結(jié)構(gòu)打交道的唯一技術(shù),我們還可以通過CSS(層疊樣式表)告訴瀏覽器怎么顯示一份文檔的內(nèi)容。
? ? 類似JavaScript腳本,對(duì)樣式的聲明既可以嵌在文檔的<head>部分(<style>標(biāo)簽之間,也可以放在另外一個(gè)樣式表文件里)。CSS聲明元素樣式的語法與JavaScript函數(shù)的定義語法很相似:
selector{
? ? property:value;
}
在樣式聲明里,我們可以定義瀏覽器在顯示元素時(shí)使用的顏色、字體和字號(hào),如下:
p{
color:yellow;
font-family:"arial",sans-serif;
font-size:1.2em}
????????繼承(inheritance)是CSS技術(shù)中的一項(xiàng)強(qiáng)大功能,例如:如果我們?yōu)閎ody元素定義了一些顏色或字體,包含在body所有元素都將自動(dòng)獲得哪些樣式。
????? ?在某些場(chǎng)合,當(dāng)樣式應(yīng)用于一份文檔時(shí),我們其實(shí)只想讓那些樣式作用于某個(gè)特定的元素。
? ??? ? 為了把某一個(gè)或幾個(gè)元素與其他元素區(qū)別開來,需要使用class屬性或id屬性。
????? ? 1、class屬性
你可以在所有元素上任意應(yīng)用class屬性:
<p class = "special">This paragraph has the special class </p>
<h2? class = "special">So does this headline</h2>
在樣式表里,可以像下面這樣為class屬性值相同的所有元素定義同一種樣式:
.special{
????font-style:italic;
}
還可以像下面這樣利用class屬性為一種特定類型的元素定義一種特定的樣式:
h2.special{
text-transform:uppercase;
}
? ? 2、id屬性
id屬性的用途是給網(wǎng)頁里的某個(gè)元素加上一個(gè)獨(dú)一無二的標(biāo)識(shí)符,如下:
<ul id = "purchases">
在這樣的樣式表里,可以像下面這樣為有特定id屬性值的元素定義一種獨(dú)享的樣式:
#purchases{
????border: 1px solid white;
????background-color:#333
????color:#ccc;
????padding:1em
}
盡管id本身只能使用一次,樣式表還是可以利用id屬性為包含在該特定元素里的其他元素定義樣式。例如:
#purchases li{
????font-weight:bold;
}
id屬性就像是一個(gè)掛鉤,它一頭連著文檔里的某個(gè)元素,另一頭連著CSS樣式表里的某個(gè)樣式,DOM也可以使用這種掛鉤。
獲取元素
有3種方法可以獲取元素節(jié)點(diǎn),分別是通過元素id、通過標(biāo)簽名字和類名字來獲取。
1、getElementById
????DOM提供了一個(gè)名為getElementById的方法,這個(gè)將返回一個(gè)與那個(gè)有著給定id屬性值得元素節(jié)點(diǎn)對(duì)應(yīng)的對(duì)象。但是請(qǐng)注意:JavaScript區(qū)分大小寫。
? ? 它是document對(duì)象所特有的函數(shù),在腳本代碼里,函數(shù)名的后面必須有一對(duì)圓括號(hào),這對(duì)圓括號(hào)包含著函數(shù)的參數(shù)。getElementById方法只有一個(gè)參數(shù):就是你想要獲得那個(gè)元素的id屬性的值,這個(gè)值必須放在單引號(hào)或者雙引號(hào)里。
document.getElementById(id);
下面是一個(gè)例子:
document.getElementById("purchases")
???????這個(gè)調(diào)用將返回一個(gè)對(duì)象,這個(gè)對(duì)象對(duì)應(yīng)著document對(duì)象里的獨(dú)一無二的元素,那個(gè)元素的HTMLid屬性值是purchases。你可以用typeof操作符來驗(yàn)證這一點(diǎn)。typeof操作符可以告我們它的操作數(shù)是一個(gè)字符串、數(shù)值、函數(shù)、布爾值還是對(duì)象。
如下:
<!DOCTYPE html> <html lang = "en"><head><meta charset = "utf-8"/><title>Shopping list</title></head><body> <h1>What to buy</h1><p title= "a gentle reminder">Don't forget to buy this stuff.</p><ul id = "purchases"><li>a tin of beans</li><li class = "sale">Cheese</li><li class = "sale important">Milk</li></ul><script>alert(typeof document.getElementById("purchases"));</script></body> </html>運(yùn)行之后,會(huì)彈出一個(gè)alert對(duì)話框,報(bào)告書document.getElementById("purchases")的類型-它是一個(gè)對(duì)象。
事實(shí)上,文檔中的每一個(gè)對(duì)象都是一個(gè)對(duì)象。利用DOM提供的方法可以得到任何一個(gè)對(duì)象。但是我們沒有必要為為文檔中的每一個(gè)元素都定義一個(gè)獨(dú)一無二的id值。DOM提供了另一個(gè)方法來獲取那些沒有id屬性的對(duì)象。
????2、getElementsByTagName
getElementByTagName方法返回一個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象分別對(duì)應(yīng)著文檔里有著給定標(biāo)簽的一個(gè)元素。類似于getElementById,這個(gè)方法也是只有一個(gè)參數(shù)的函數(shù),它的參數(shù)是標(biāo)簽的名字:
element.getElementsByTagName(tag)
它與getElementById方法有許多類似之處,但是它返回的是一個(gè)數(shù)組。
例子:
document.getElementByTagName("li"),這個(gè)調(diào)用將返回一個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象分別對(duì)應(yīng)著document對(duì)象中的一個(gè)列表項(xiàng)元素。與任何其他的數(shù)組一樣,我們可以利用length屬性查出這個(gè)數(shù)組里的元素個(gè)數(shù)。
我們把原來的里中的<script>標(biāo)簽中的alert語句替換成這條語句:
你會(huì)看到這份文檔里的列表項(xiàng)元素的個(gè)數(shù):3。這個(gè)數(shù)組里的每個(gè)元素都是一個(gè)對(duì)象。可以利用循環(huán)語句和typeof操作符去遍歷這個(gè)數(shù)組來驗(yàn)證這一點(diǎn)。例如:
for(var i = 0;i<document.getElementsByTagName("li").length;i++){
alert(typeof document.getElementByTagName("li")[i]);
}
注意:即使在整個(gè)文檔里這個(gè)標(biāo)簽里只有一個(gè)元素,getElementByTagName也返回一個(gè)數(shù)組,此時(shí),那個(gè)數(shù)組的長(zhǎng)度是1。
為了改善代碼的可讀性;只要把document.getElementByTagName("li")賦值給一個(gè)變量即可。
請(qǐng)把<script>標(biāo)簽中的alert語句替換成下面這些語句:
var items = document.getElementsByTagName("li");
for(var i =0;i<items.length;i++){
????alert(typeof items[i])
}
即:
<!DOCTYPE html> <html lang = "en"><head><meta charset = "utf-8"/><title>Shopping list</title></head><body> <h1>What to buy</h1><p title= "a gentle reminder">Don't forget to buy this stuff.</p><ul id = "purchases"><li>a tin of beans</li><li class = "sale">Cheese</li><li class = "sale important">Milk</li></ul><script>var items = document.getElementsByTagName("li");for(var i =0;i<items.length;i++){alert(typeof items[i])}</script></body> </html>????我們可以到有三個(gè)alert對(duì)話框;顯示消息都是”object“。
此外:
????? ? getElementsByTagName允許把一個(gè)通配符作為它的參數(shù),而這意味著文檔里的每個(gè)元素都將在這個(gè)函數(shù)所返回的數(shù)組里占有一席之地。通配符(星號(hào)字符"*")必須放在引號(hào)里,這是為了讓通配符與乘法操作符有所區(qū)別。如果你想知道某份文檔中有多少個(gè)元素節(jié)點(diǎn),像下面這樣使用通配符即可:
????alert(document.getElementsByTagName("*").length);
還可以:
? ? 把getElementsByTagName()與getElementById()結(jié)合起來一起使用。如果只想知道id屬性值是purchases的元素包含了多少個(gè)列表項(xiàng),必須通過一個(gè)更具體的對(duì)象去調(diào)用這個(gè)方法,如下:
????? ? var shopping = document.getElementById("purchases");
????? ? var items = shopping.getElementsByTagName("*");
這兩條語句執(zhí)行完畢之后,items數(shù)據(jù)將只包含id屬性值是purchase的無序清單里的元素。具體到這個(gè)例子,items數(shù)組里的長(zhǎng)度剛好與這份文檔里的列表項(xiàng)元素的總數(shù)相等:
alert(items.length);
如果還需要跟多的證據(jù),下面這些語句將證明items數(shù)組里的每個(gè)值確實(shí)一個(gè)對(duì)象:
for(var i = 0;i<items.length;i++){
????alert(typeof item[i]);
}
3、getElementsByClassName
HTML5 DOM中新增了一個(gè)令人期待已久的方法:getElementsByClassName。這個(gè)方法讓我們能夠通過class屬性中的類名來訪問元素。
與getElementsByTagName()方法類似,getElementsByClassName也是只接受一個(gè)參數(shù),就是類名:
? ? getElementsByClassName(class)
這個(gè)方法與getElementsByTagName類似,都是一個(gè)具有相同類名的元素的數(shù)組。下面這行代碼返回的就是一個(gè)數(shù)組,其中包含類名為"sale"的所有元素:
document.getElementsByClassName("sale");
使用這個(gè)方法還可以查找那些帶有多個(gè)類名的元素。要指定多個(gè)類名,只要在字符串參數(shù)中用空格分隔類名即可。例如:
在<script>標(biāo)簽中添加這行alert代碼:
alert(document.getElementsByClassName("important? sale").length);
你會(huì)發(fā)現(xiàn)只有一個(gè)元素同時(shí)帶有"important"和"sale"類名。注意:即使在元素的class屬性中,類名的順序是"sale important"而非參數(shù)指定的"important sale",也會(huì)照樣匹配該元素。不僅類名的實(shí)際順序不重要,就算元素還帶有更多的類名也沒有關(guān)系。
? ? 與使用getElementsByTagName一樣,也可以組合使用getElementsByClassName和getElementById。如果你想知道在id位"purchases"的元素中有多少類名包含"sale"列表項(xiàng)。可以先找到那個(gè)特定的對(duì)象,然后再調(diào)用getElementsByClassName:
var shopping = document.getElementById("purchases");
var sales = shopping.getElementsByClassName("sale");
這樣,sales數(shù)組中就包含的就只是位于"purchases"列表項(xiàng)中的帶有"sale"類的元素。
運(yùn)行代碼:alert(sales.length);。
盤點(diǎn)知識(shí)點(diǎn):
- 一份文檔就是一顆節(jié)點(diǎn)樹
- 節(jié)點(diǎn)分為不同的類型:元素節(jié)點(diǎn)、屬性節(jié)點(diǎn)和文本節(jié)點(diǎn)。
- getElementById將返回一個(gè)對(duì)象,該對(duì)象對(duì)應(yīng)著文檔里的一個(gè)特定元素節(jié)點(diǎn)。
- getElementsByTagName和getElementsByClassName將返回一個(gè)對(duì)象數(shù)組,它們分別對(duì)應(yīng)著文檔里的一組特定的元素節(jié)點(diǎn)。
- 每個(gè)節(jié)點(diǎn)都是一個(gè)對(duì)象。
5、獲取和設(shè)置屬性
我們有三種獲取特定元素的方法,得到需要的元素之后,我們就可以使用getAttribute方法獲取它的各個(gè)屬性。setAttribute()方法則可以更改屬性節(jié)點(diǎn)的值。
getAttribute方法不屬于document對(duì)象,所有不能通過document對(duì)象來調(diào)用。它之只能通過元素節(jié)點(diǎn)對(duì)象調(diào)用。可以通過getElementsByTagName方法合用,獲取每個(gè)<p>元素的title屬性,如下所示:
var paras = document.getElementsByTagName("p");
for(var i = 0;i < paras.length;i++){
???????alert(paras[i].getAttribute("title"));
}
例如:
會(huì)彈出什么呢?
在文檔文件中,只有一個(gè)p元素,并且它有title屬性。假如這份文檔有更多個(gè)<p>元素,并且沒有title屬性,則getAttribute("title")方法會(huì)返回null值。在JavaScript里面,null的含義是"沒有值"。我們可以試試再添加一個(gè)<p>標(biāo)簽;
<p>This is just a test </p>
如:
<!DOCTYPE html> <html lang = "en"><head><meta charset = "utf-8"/><title>Shopping list</title></head><body> <h1>What to buy</h1><p title= "a gentle reminder">Don't forget to buy this stuff.</p><p>This is just a test </p><ul id = "purchases"><li>a tin of beans</li><li class = "sale">Cheese</li><li class = "sale important">Milk</li></ul><script>var paras = document.getElementsByTagName("p");for(var i = 0;i < paras.length;i++){alert(paras[i].getAttribute("title"));}</script></body> </html>重新加載這個(gè)頁面。會(huì)出現(xiàn)什么呢?
我們可以修該腳本,讓它只在title屬性有值時(shí)才彈出消息。我們?cè)黾右粭lif語句來檢查getAttribute的返回值是不是null。
如下:
var paras? = document.getElementsByTagName("p");
for(var i = 0;i <paras.length;i++){
????var title_text =paras[i].getAttribute("title");
????if(title_text != null)
????alert(title_texg);
}
重新加載,又會(huì)出現(xiàn)什么呢?
setAttribute
它允許我們對(duì)屬性節(jié)點(diǎn)的值做出修該。與getAttribute一樣。setAttribute也只能用于元素節(jié)點(diǎn):
? ? object.setAttribute(attribute,value)
例子:
var shopping = document.getElementById("purchases"); alert (shopping.getAttribute("title")); shopping.setAttribute("title","a list of goods"); alert (shopping.getAttribute("title"));運(yùn)行之后,會(huì)出現(xiàn)什么呢?
還有一個(gè)細(xì)節(jié):通過setAttribute對(duì)文檔做出修改后,在通過瀏覽器的view source(查看源代碼)選項(xiàng)去查看文檔的源代碼時(shí)看到的仍然是改變前的屬性值,也就是說,setAttribute做出的修該不會(huì)反映在文檔本身的源代碼里。這種“表里不一”的現(xiàn)象源自DOM的工作模式:先加載文檔的靜態(tài)內(nèi)容,在動(dòng)態(tài)刷新,動(dòng)態(tài)刷新不影響文檔的靜態(tài)內(nèi)容。這是DOM的真正威力:對(duì)頁面內(nèi)容進(jìn)行刷新卻不需要在瀏覽器里刷新頁面。
總結(jié)
以上是生活随笔為你收集整理的JavaScript 第三课 DOM的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu 10.04解决Skype中
- 下一篇: 前端学习(492):script之标签得