了解dom
在這一部分,你将開始探索文檔對象模型(dom)。通過使用dom,你能夠添加、移除和操作各種元素。還可以使用事件(event)來響應使用者的互動操作,以及完全控制css。
從這裡開始,你就處于html5的程式設計部分了。在此之前,你已經用元素和css聲明建立了内容,現在是時候以程式員的身份開始使用javascript了。
dom是一組對象的集合,這些對象代表了html文檔裡的各個元素。顧名思義,dom就像一個模型,它由代表文檔的衆多對象組成。dom是web開發的關鍵工具之一,它是html文檔的結構和内容與javascript之間的橋梁。作為示例,代碼清單1展示了一個簡單的html文檔。
從上圖可以看到浏覽器是如何顯示上述示例html文檔的。
作為顯示html文檔過程中的一個步驟,浏覽器會解析html并建立一個模型。這個模型儲存了各個html元素之間的層級關系(如下圖所示),每個元素都由一個javascript對象表示。
你可以用dom來擷取文檔資訊,也可以對其進行修改。這是現代web應用程式的基礎。
模型裡的每一個對象都有若幹屬性和方法。當你用它們來修改對象的狀态時,浏覽器會讓這些改動反映到對應的html元素上,并更新你的文檔。
所有代表元素的dom象都支援同一組基本功能:htmlelement對象和其定義的核心功能始終是可用的,無論對象代表何種元素都是如此。另外,某些對象會定義一些額外的功能,這些操作反映了特定html元素獨一無二的特性。記住下面的一點很重要:文檔模型裡任何代表某個元素的對象都至少能支援htmlelement功能,其中一些還支援額外的功能。
不是所有可供使用的對象都代表了html元素。正如你即将看到的,一些對象代表元素的集合,另一些則代表dom自身的資訊,當然還有document這個對象,它是我們探索dom的入口。
如果你熟悉面向對象程式設計的概念,那麼了解htmlelement是一個接口可能會有所幫助,它是由dom所包含的對象實作的。用于代表具體元素的對象是htmlelement派生出來的接口,意思是你既可以把某個對象當做htmlelement的實作,也可以當做其更為具體的子類型。如果你不熟悉面向對象的概念也不用擔心。對主流web程式設計而言,是否了解它們無關緊要。簡單起見,下面将把所有的一切都稱為對象。
開始使用dom時,你會碰到網絡上一些文章和教程提到dom level(dom等級,比如某個特定功能是在dom level3中定義的)。dom level是标準化過程中的版本号,在大多數情況下應該忽略它們。
dom的标準化過程并不是完全成功的,每一個dom level都有描述它的标準和文檔,但它們并沒有被完整地實作,浏覽器隻是簡單地挑選了其中的有用功能,而忽略了其他的。更糟糕的是,已經實作的功能之間還存在着某種程度的不一緻性。
部分問題在于,dom規範與html标準過去是分别開發的。html5試圖通過包含一組必須實作的dom核心功能來解決這個問題。然而這種做法尚未見效,碎片化仍然存在。
有多種方式可用來應對dom功能的多變性。第一種方式是使用某個javascript庫(比如jquery),它消除了浏覽器之間實作方式的差别。使用庫的優點在于其一緻性,但缺點是隻能使用庫支援的那些功能。如果想突破庫原有功能的局限,就隻能轉回到直接操作dom上,并重新面對之前的那些問題。(這并不是說jquery和類似的庫沒有價值,它們很有用,非常值得去了解一下。)
第二種是保守方式:隻使用你所知的被廣泛支援的那些功能。這種方式一般來說是最為明智的,不過它需要仔細而全面的測試。不僅如此,你還必須仔細測試新版的浏覽器,確定對這些功能的支援沒有發生變化或者被移除。
第三種方式是測試與某一功能相關的dom對象屬性或方法是否存在。代碼清單2包含了一個簡單的例子。
在這個例子裡,腳本使用一條if語句來判斷document對象是否定義了一個名為queryselectorall的方法。如果這條語句的計算結果是true,那麼浏覽器是支援這一功能的,我就可以開始使用它。如果該語句的計算結果是false,那麼我可以換一種方式來達到同樣的目的。
談到dom時,你經常看到的就是剛才這種建議,但它過于草率,沒有指出其中的缺陷,而這些缺陷有可能很嚴重。
第一個缺陷在于,并不總是存在另一種方式能實作某個給定功能的效果。代碼清單2能順利工作是因為我測試的功能是其他函數的一種便利性加強形式,但情況并不總是如此。
第二個缺陷是我隻測試了該功能是否存在,而不是它的實作品質和一緻性。許多功能(特别是新的功能)需要多個版本的浏覽器才能穩定下來并實作一緻性。雖然這個問題不像以前那樣嚴重,但你也許很容易就會遇到意料之外的結果,因為你依賴的浏覽器功能實作方式存在差别。
第三個缺陷是必須測試每一種你所依賴的功能。這麼做需要耗費大量的精力,而且産生的代碼充斥着無窮無盡的測試。我并不是說它不是一種有用的技巧,而是它存在缺陷,不應該取代恰當的測試。
以下部分提供了對象、方法、屬性和事件的快速查詢。
document對象,它代表目前的文檔,也是你探索dom的入口。下表概述了此對象所定義的成員。
名 稱
說 明
返 回
activeelement
傳回代表文檔中目前獲得焦點元素的對象
htmlelement
body
傳回代表文檔中body元素的對象
characterset
傳回文檔的字元集編碼。這是一個隻讀屬性
字元串
charset
擷取或設定文檔的字元集編碼
childnodes
傳回子元素的集合
htmlelement[]
compatmode
擷取文檔的相容性模式
cookie
擷取或設定目前文檔的cookie
defaultcharset
擷取浏覽器所使用的預設字元編碼
defaultview
傳回目前文檔的window對象
window
dir
擷取或設定文檔的文本方向
domain
擷取或設定目前文檔的域名
embeds、plugins
傳回所有代表文檔中embed元素的對象
htmlcollection
firstchild
傳回某個元素的第一個子元素
forms
傳回所有代表文檔中form元素的對象
getelementbyid(<<code>id</code>>)
傳回帶有指定id值的元素
getelementsbyclassname(<<code>class</code>>)
傳回帶有指定class值的元素
getelementsbyname(<<code>name</code>>)
傳回帶有指定name值的元素
getelementsbytagname(<<code>tag</code>>)
傳回帶有指定類型的元素
haschildnodes()
如果目前元素有子元素則傳回true
布爾值
head
傳回代表head元素的對象
htmlheadelement
images
傳回所有代表img元素的對象
implementation
提供關于dom可用功能的資訊
domimplementation
lastchild
傳回最後一個子元素
lastmodified
傳回文檔的最後修改時間
links
傳回所有代表文檔中具備href的a和area元素的對象
location
提供關于目前文檔url的資訊
nextsibling
傳回位于目前元素之後的兄弟元素
parentnode
傳回父元素
previoussibling
傳回位于目前元素之前的兄弟元素
queryselector(<<code>selector</code>>)
傳回比對特定css選擇器的第一個元素
queryselectorall(<<code>selector</code>>)
傳回比對特定css選擇器的所有元素
readystate
傳回目前文檔的狀态
referrer
傳回連結到目前文檔的文檔url (它是對應http标頭的值)
scripts
傳回所有代表script元素的對象
title
擷取或設定目前文檔的标題
下表概述了location對象。
assign(<<code>url</code>>)
導航到指定的url上
void
hash
擷取或設定文檔url的錨(井号串)部分
host
擷取或設定文檔url的主機名和端口号部分
hostname
擷取或設定文檔url的主機名部分
href
擷取或設定目前文檔的位址
pathname
擷取或設定文檔url的路徑部分
port
擷取或設定文檔url的端口号部分
protocol
擷取或設定文檔url的協定部分
reload()
重新加載目前文檔
replace(<<code>url</code>>)
清除目前文檔并導航至url所指定的新文檔
resolveurl(<<code>url</code>>)
将指定的相對url解析為絕對url
search
擷取或設定文檔url的查詢(問号串)部分
alert(<<code>msg</code>>)
向使用者顯示一個對話框視窗并等候其被關閉
blur()
讓視窗失去鍵盤焦點
clearlnterval(<<code>id</code>>)
撤銷某個時間間隔計時器
cleartimeout(<<code>id</code>>)
撤銷某個逾時計時器
close()
關閉視窗
confirm(<<code>msg</code>>)
顯示一個帶有确認和取消提示的對話框視窗
傳回活動文檔的window
document
傳回與此視窗關聯的document對象
focus()
讓視窗獲得鍵盤焦點
frames
傳回文檔内嵌iframe元素的window對象數組
window[]
history
提供對浏覽器曆史的通路
innerheight
擷取視窗内容區域的高度
數值
innerwidth
擷取視窗内容區域的寬度
length
傳回文檔内嵌的iframe元素數量
提供目前文檔位址的詳細資訊
opener
傳回打開目前浏覽器上下文環境window
outerheight
擷取視窗的高度,包括邊框和菜單欄等
outerwidth
擷取視窗的寬度,包括邊框和菜單欄等
pagexoffet
擷取視窗從左上角算起水準滾動過的像素數
pageyoffset
擷取視窗從左上角算起垂直滾動過的像素數
parent
傳回目前window的父window
postmessage(<<code>msg</code>>,<<code>origin</code>>)
給另一個文檔發送消息
print()
提示使用者列印頁面
prompt(<<code>msg</code>>, <<code>val</code>>)
顯示對話框提示使用者輸入一個值
screen
傳回一個描述螢幕的screed象
screenleft、screenx
擷取從視窗左邊緣到螢幕左邊緣的像素數
screentop、screeny
擷取從視窗上邊緣到螢幕上邊緣的像素數
scrollby(<<code>x</code>>, <<code>y</code>>)
讓文檔相對其目前位置進行滾動
scrollto(<<code>x</code>>, <<code>y</code>>)
滾動到指定的位置
self
傳回目前文檔的window
setinterval(<<code>function</code>>, <<code>time</code>>)
建立一個計時器,每隔time毫秒調用指定的函數
整數
settimeout(<<code>function</code>>, <<code>time</code>>)
建立一個計時器,等待time毫秒後調用指定的函數
showmodaldialog(<<code>url</code>>)
彈出一個視窗,顯示指定的url
stop()
停止載入文檔
top
傳回最上層的window
下表概述了history對象的成員。
名稱
back()
在浏覽曆史裡後退一步
forward()
在浏覽曆史裡前進一步
go(<<code>index</code>>)
轉到相對于目前文檔的某個浏覽曆史位置。正值是前進,負值是後退
傳回浏覽曆史裡的項目數量
pushstate(<<code>state</code>>, <<code>title</code>>, <<code>url</code>>)
向浏覽器曆史添加一個條目
replacestate(<<code>state</code>>, <<code>title</code>>, <<code>url</code>>)
替換浏覽器曆史中的目前條目
state
傳回浏覽器曆史裡關聯目前文檔的狀态資料
對象
下表概述了screen對象的成員。
availheight
傳回螢幕上可供顯示視窗部分的高度(排除工具欄之類)
availwidth
傳回螢幕上可供顯示視窗部分的寬度(排除工具欄之類)
colordepth
傳回螢幕的顔色深度
height
傳回螢幕的高度
width
傳回螢幕的寬度
htmlelement對象,它代表了文檔裡的各種html元素。下表概述了此對象定義的成員。
checked
擷取或設定checked屬性的存在狀态
classlist
擷取或設定元素所屬類的清單
domtokenlist
classname
擷取或設定dir屬性的值
disabled
擷取或設定disabled屬性的存在狀态
hidden
擷取或設定hidden屬性的存在狀态
id
擷取或設定id屬性的值
lang
擷取或設定lang屬性的值
spellcheck
擷取或設定spellcheck屬性的存在狀态
tabindex
擷取或設定tabindex屬性的值
tagname
傳回标簽名(象征元素的類型)
擷取或設定title屬性的值
add(<<code>class</code>>)
給元素添加指定的類
contains(<<code>class</code>>)
如果元素屬于指定的類則傳回true
傳回元素所屬類的數量
remove(<<code>class</code>>)
從元素上移除指定的類
toggle(<<code>class</code>>)
如果類不存在就添加它,如果存在則移除它
attributes
傳回應用到元素上的屬性
attr[]
dataset
傳回以data-開頭的屬性
字元串數組[<<code>name</code>>]
getattribute(<<code>name</code>>)
傳回指定屬性的值
hasattribute(<<code>name</code>>)
如果元素帶有指定屬性則傳回true
removeattribute(<<code>name</code>>)
從元素上移除指定屬性
setattribute(<<code>name</code>>, <<code>value</code>>)
應用一個指定名稱和值的屬性
appendchild(htmlelement)
将指定元素附加為目前元素的子元素
clonenode(boolean)
複制某個元素
comparedocumentposition(htmlelement)
判斷某個元素的相對位置
innerhtml
擷取或設定元素的内容
insertadjacenthtml(〈<code>pos</code>〉,<<code>text</code>>)
相對于元素的位置插入html
insertbefore(<<code>newelem</code>>, <<code>childelem</code>>)
将第一個元素插入到第二個(子)元素之前
isequalnode(<<code>htmlelement</code>>)
判斷指定元素是否與目前元素等同
issamenode(htmlelement)
判斷指定元素是否就是目前元素
outerhtml
擷取或設定某個元素的html和内容
removechild(htmlelement)
從目前元素上移除指定的子元素
replacechild(htmlelement, htmlelement)
替換目前元素的某個子元素
createelement(<<code>tag</code>>)
用指定标簽類型建立一個新的htmlelement對象
createtextnode(<<code>text</code>>)
用指定内容建立一個新的text對象
text
text對象,它用于代表文檔中的文本内容。下表描述了text對象的成員。
appenddata(<<code>string</code>>)
在文本塊的末尾附加指定字元串
data
擷取或設定文本
deletedata(<<code>offset</code>>, <<code>count</code>>)
移除字元串中的文本。第一個數字是偏移量,第二個數字是要移除的字元數量
insertdata(<<code>offset</code>>, <<code>string</code>>)
在指定的偏移量位置插入指定字元串
傳回字元數量
replacedata(<<code>offset</code>>, <<code>count</code>>, <<code>string</code>>)
用指定字元串替換一部分文本
replacewholetext(<<code>string</code>>)
替換全部文本
splittext(<<code>number</code>>)
将現有的text元素在指定的偏移量處一分為二。
substringdata(<<code>offset</code>>, <<code>count</code>>)
傳回文本的子串
wholetext
擷取文本
下表列出了cssstyledeclaration對象的屬性和它們所對應的樣式。
成 員
對應于
background
backgroundattachment
background-attachment
backgroundcolor
background-color
backgroundimage
background-image
backgroundposition
background-position
backgroundrepeat
background-repeat
border
borderbottom
border-bottom
borderbottomcolor
border-bottom-color
borderbottomstyle
border-bottom-style
borderbottomwidth
border-bottom-width
bordercollapse
border-collapse
bordercolor
border-color
borderleft
border-left
borderleftcolor
border-left-color
borderleftstyle
border-left-style
borderleftwidth
border-left-width
borderright
border-right
borderrightcolor
border-right-color
borderrightstyle
border-right-style
borderrightwidth
border-iight-width
borderspacing
border-spacing
borderstyle
border-style
bordertop
border-top
bordertopcolor
border-top-color
bordertopstyle
boider-top-style
bordertopwidth
border-top-width
borderwidth
border-width
captionside
caption-side
clear
color
cssfloat
float
cursor
direction
display
emptycells
empty-cells
font
fontfamily
font-family
fontsize
font-size
fontstyle
font-style
fontvariant
font-variant
fontweight
font-weight
letterspacing
letter-spacing
lineheight
line-height
liststyle
list-style
liststylelmage
list-style-image
liststyleposition
list-style-position
liststyletype
list-style-type
margin
marginbottom
margin-bottom
marginleft
margin-left
marginright
margin-right
margintop
margin-top
maxheight
max-height
maxwidth
max-width
minheight
min-height
minwidth
min-width
outline
outlinecolor
outline-color
outlinestyle
outline-style
outlinewidth
outline-width
overflow
padding
paddingbottom
padding-bottom
paddingleft
padding-left
paddingright
padding-right
paddingtop
padding-top
tablelayout
table-layout
textalign
text-align
textdecoration
text-decoration
textindent
text-indent
textshadow
text-shadow
texttransform
text-transform
visibility
whitespace
wordspacing
word-spacing
zindex
z-index
dom的事件系統,有許多不同的事件可供使用,如下表所示。
blur
在元素失去鍵盤焦點時觸發
click
在按下滑鼠按鈕後釋放時觸發
dblclick
在兩次按下滑鼠按鈕并釋放時觸發
focus
在元素獲得鍵盤焦點時觸發
focusin
在元素即将獲得鍵盤焦點時觸發
focusout
在元素即将失去鍵盤焦點時觸發
keydown
在使用者按下某個鍵時觸發
keypress
在使用者按下某個鍵并釋放時觸發
keyup
在使用者釋放某個鍵時觸發
mousedown
在滑鼠按鈕被按下時觸發
mouseenter
在光标移入元素或其下屬元素所占據的螢幕區域時觸發
mouseleave
在光标移出元素及其所有下屬元素所占據的螢幕區域時觸發
mousemove
在光标位于元素上方并移動時觸發
mouseout
與mouseleave相似,差別是當光标還在下屬元素上方時此事件也會被觸發
mouseover
與mouseenter相似,差別是當光标還在下屬元素上方時此事件也會被觸發
mouseup
在滑鼠按鈕被釋放時觸發
onabort
在文檔或資源的加載過程被中止時觸發
onafterprint
在使用者列印文檔後觸發
onbeforeprint
在調用window.print()方法之後,向使用者呈現列印選項之前觸發
onerror
在文檔或資源載入岀錯時觸發
onhashchange
在位址的錨(井号串)部分變動時觸發
onload
在文檔或資源載入完成時觸發
onpopstate
觸發時會提供一個關聯浏覽器曆史的狀态對象
onresize
在視窗大小改變時觸發
onunload
在文檔從視窗或浏覽器中解除安裝時觸發
readystatechange
在ready state屬性的值改變時觸發
reset
在某張表單被重置時觸發
submit
在某張表單被送出時觸發