理解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
在某张表单被提交时触发