黄子涵

第 25 章 理解DOM

在这一部分,你将开始探索文档对象模型(DOM)。通过使用DOM,你能够添加、移除和操作各种元素。还可以使用事件(event)来响应用户的交互操作,以及完全控制CSS。

从这里开始,你就处于HTML5的程序设计部分了。在此之前,你已经用元素和CSS声明创建了内容,现在是时候以程序员的身份开始使用JavaScript了。

理解文档对象模型

DOM是一组对象的集合,这些对象代表了HTML文档里的各个元素。顾名思义,DOM就像一个模型,它由代表文档的众多对象组成。DOM是Web开发的关键工具之一,它是HTML文档的结构和内容与JavaScript之间的桥梁。作为示例,代码清单1展示了一个简单的HTML文档。

代码清单1 一个简单的HTML文档

<!DOCTYPE>
<html>
    <head>
        <title>一个简单的HTML文档</title>
        <meta name="作者" content="黄子涵"/>
        <meta name="描述" content="一个简单的例子"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    
    <body>
        <p id="FloatingLife">
            <span id="monologue">独白:</span><br>
            <br>
            当你意识到自己其实已经不再那么年轻<br>
            每天周而复始的过着自己可能并不喜欢却无法改变的生活<br>
            做着自己并不喜欢的工作<br>
            人生的选择题<br>
            是要继续甘于平庸<br>
            还是奋力一搏去追求自己所想要的<br>
            成功或者失败<br>
            得到或者失去<br>
            也往往不那么重要<br>
            因为我们只想要当下<br>
        </p>
        
        <P id="DifficultSutra">
            吞风吻雨葬落日未曾彷徨<br> 
            欺山赶海践雪径也未绝望<br>
            拈花把酒偏折煞世人情狂<br>
            凭这两眼与百臂或千手不能防<br>
            天阔阔雪漫漫共谁同航<br>
            这沙滚滚水皱皱笑着浪荡<br>
            贪欢一晌偏教那女儿情长埋葬<br>
        </P>
    </body>
</html>

image

从上图可以看到浏览器是如何显示上述示例HTML文档的。

作为显示HTML文档过程中的一个步骤,浏览器会解析HTML并创建一个模型。这个模型保存了各个HTML元素之间的层级关系(如下图所示),每个元素都由一个JavaScript对象表示。

image

你可以用DOM来获取文档信息,也可以对其进行修改。这是现代Web应用程序的基础。

模型里的每一个对象都有若干属性和方法。当你用它们来修改对象的状态时,浏览器会让这些改动反映到对应的HTML元素上,并更新你的文档。

所有代表元素的DOM象都支持同一组基本功能:HTMLElement对象和其定义的核心功能始终是可用的,无论对象代表何种元素都是如此。另外,某些对象会定义一些额外的功能,这些操作反映了特定HTML元素独一无二的特性。记住下面的一点很重要:文档模型里任何代表某个元素的对象都至少能支持HTMLElement功能,其中一些还支持额外的功能。

不是所有可供使用的对象都代表了HTML元素。正如你即将看到的,一些对象代表元素的集合,另一些则代表DOM自身的信息,当然还有Document这个对象,它是我们探索DOM的入口。


注意

如果你熟悉面向对象程序设计的概念,那么了解HTMLElement是一个接口可能会有所帮助,它是由DOM所包含的对象实现的。用于代表具体元素的对象是HTMLElement派生出来的接口,意思是你既可以把某个对象当做HTMLElement的实现,也可以当做其更为具体的子类型。如果你不熟悉面向对象的概念也不用担心。对主流Web程序设计而言,是否理解它们无关紧要。简单起见,下面将把所有的一切都称为对象。


理解DOM Level和兼容性

开始使用DOM时,你会碰到网络上一些文章和教程提到DOM Level(DOM等级,比如某个特定功能是在DOM Level3中定义的)。DOM Level是标准化过程中的版本号,在大多数情况下应该忽略它们。

DOM的标准化过程并不是完全成功的,每一个DOM Level都有描述它的标准和文档,但它们并没有被完整地实现,浏览器只是简单地挑选了其中的有用功能,而忽略了其他的。更糟糕的是,已经实现的功能之间还存在着某种程度的不一致性。

部分问题在于,DOM规范与HTML标准过去是分别开发的。HTML5试图通过包含一组必须实现的DOM核心功能来解决这个问题。然而这种做法尚未见效,碎片化仍然存在。

有多种方式可用来应对DOM功能的多变性。第一种方式是使用某个JavaScript库(比如jQuery),它消除了浏览器之间实现方式的差别。使用库的优点在于其一致性,但缺点是只能使用库支持的那些功能。如果想突破库原有功能的局限,就只能转回到直接操作DOM上,并重新面对之前的那些问题。(这并不是说jQuery和类似的库没有价值,它们很有用,非常值得去了解一下。)

第二种是保守方式:只使用你所知的被广泛支持的那些功能。这种方式一般来说是最为明智的,不过它需要仔细而全面的测试。不仅如此,你还必须仔细测试新版的浏览器,确保对这些功能的支持没有发生变化或者被移除。

测试DOM功能

第三种方式是测试与某一功能相关的DOM对象属性或方法是否存在。代码清单2包含了一个简单的例子。

代码清单2 测试某个功能

<!DOCTYPE>
<html>
    <head>
        <title>测试某个功能</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    
    <body>
        <p id="MoveBack">
            天空灰得像哭过<br>
            酸酸的空气<br>
            嗅出我们的距离<br>
            一幕锥心的结局<br>
            像呼吸般无法停息<br>
            抽屉泛黄的日记<br>
            榨干了回忆<br>
            <img src="http://120.77.46.246/src/img/Xu_Weizhou.jpeg">
        </p>
        <script>
            var images;
            if (document.querySelectorAll) {
                images = document.querySelectorAll("#MoveBack > img");
            } else {
                images = document.getElementById("MoveBack").getElementsByTagName("img");
            }
            
            for (var i = 0; i < images.length; i++) {
                images[i].style.border = "thick soild balck";
                images[i].style.padding = "4px";
            }
        </script>
    </body>
</html>

image

在这个例子里,脚本使用一条if语句来判断document对象是否定义了一个名为querySelectorAll的方法。如果这条语句的计算结果是true,那么浏览器是支持这一功能的,我就可以开始使用它。如果该语句的计算结果是false,那么我可以换一种方式来达到同样的目的。

谈到DOM时,你经常看到的就是刚才这种建议,但它过于草率,没有指出其中的缺陷,而这些缺陷有可能很严重。

第一个缺陷在于,并不总是存在另一种方式能实现某个给定功能的效果。代码清单2能顺利工作是因为我测试的功能是其他函数的一种便利性加强形式,但情况并不总是如此。

第二个缺陷是我只测试了该功能是否存在,而不是它的实现质量和一致性。许多功能(特别是新的功能)需要多个版本的浏览器才能稳定下来并实现一致性。虽然这个问题不像以前那样严重,但你也许很容易就会遇到意料之外的结果,因为你依赖的浏览器功能实现方式存在差别。

第三个缺陷是必须测试每一种你所依赖的功能。这么做需要耗费大量的精力,而且产生的代码充斥着无穷无尽的测试。我并不是说它不是一种有用的技巧,而是它存在缺陷,不应该取代恰当的测试。

DOM快速查询

以下部分提供了对象、方法、属性和事件的快速查询。

Document的成员

Document对象,它代表当前的文档,也是你探索DOM的入口。下表概述了此对象所定义的成员。

Document对象

名 称 说 明 返 回
activeElement 返回代表文档中当前获得焦点元素的对象 HTMLElement
body 返回代表文档中body元素的对象 HTMLElement
characterSet 返回文档的字符集编码。这是一个只读属性 字符串
charset 获取或设置文档的字符集编码 字符串
childNodes 返回子元素的集合 HTMLElement[]
compatMode 获取文档的兼容性模式 字符串
cookie 获取或设置当前文档的cookie 字符串
defaultCharset 获取浏览器所使用的默认字符编码 字符串
defaultview 返回当前文档的Window对象 Window
dir 获取或设置文档的文本方向 字符串
domain 获取或设置当前文档的域名 字符串
embeds、plugins 返回所有代表文档中embed元素的对象 HTMLCollection
firstChild 返回某个元素的第一个子元素 HTMLElement
forms 返回所有代表文档中form元素的对象 HTMLCollection
getElementById(<id>) 返回带有指定id值的元素 HTMLElement
getElementsByClassName(<class>) 返回带有指定class值的元素 HTMLElement[]
getElementsByName(<name>) 返回带有指定name值的元素 HTMLElement[]
getElementsByTagName(<tag>) 返回带有指定类型的元素 HTMLElement[]
hasChildNodes() 如果当前元素有子元素则返回true 布尔值
head 返回代表head元素的对象 HTMLHeadElement
images 返回所有代表img元素的对象 HTMLCollection
implementation 提供关于DOM可用功能的信息 DOMImplementation
lastchild 返回最后一个子元素 HTMLElement
lastModified 返回文档的最后修改时间 字符串
links 返回所有代表文档中具备href的a和area元素的对象 HTMLCollection
location 提供关于当前文档URL的信息 Location
nextSibling 返回位于当前元素之后的兄弟元素 HTMLElement
parentNode 返回父元素 HTMLElement
previousSibling 返回位于当前元素之前的兄弟元素 HTMLElement
querySelector(<selector>) 返回匹配特定CSS选择器的第一个元素 HTMLElement
querySelectorAll(<selector>) 返回匹配特定CSS选择器的所有元素 HTMLElement[]
readyState 返回当前文档的状态 字符串
referrer 返回链接到当前文档的文档URL (它是对应HTTP标头的值) 字符串
scripts 返回所有代表script元素的对象 HTMLCollection
title 获取或设置当前文档的标题 字符串

下表概述了Location对象。

Location 对象

名 称 说 明 返 回
assign(<URL>) 导航到指定的URL上 void
hash 获取或设置文档URL的锚(井号串)部分 字符串
host 获取或设置文档URL的主机名和端口号部分 字符串
hostname 获取或设置文档URL的主机名部分 字符串
href 获取或设置当前文档的地址 字符串
pathname 获取或设置文档URL的路径部分 字符串
port 获取或设置文档URL的端口号部分 字符串
protocol 获取或设置文档URL的协议部分 字符串
reload() 重新加载当前文档 void
replace(<URL>) 清除当前文档并导航至URL所指定的新文档 void
resolveURL(<URL>) 将指定的相对URL解析为绝对URL 字符串
search 获取或设置文档URL的查询(问号串)部分 字符串

Window 的成员

Window对象

名 称 说 明 返 回
alert(<msg>) 向用户显示一个对话框窗口并等候其被关闭 void
blur() 让窗口失去键盘焦点 void
clearlnterval(<id>) 撤销某个时间间隔计时器 void
clearTimeout(<id>) 撤销某个超时计时器 void
close() 关闭窗口 void
confirm(<msg>) 显示一个带有确认和取消提示的对话框窗口 布尔值
defaultView 返回活动文档的Window Window
document 返回与此窗口关联的Document对象 Document
focus() 让窗口获得键盘焦点 void
frames 返回文档内嵌iframe元素的Window对象数组 Window[]
history 提供对浏览器历史的访问 History
innerHeight 获取窗口内容区域的高度 数值
innerWidth 获取窗口内容区域的宽度 数值
length 返回文档内嵌的iframe元素数量 数值
location 提供当前文档地址的详细信息 Location
opener 返回打开当前浏览器上下文环境Window Window
outerHeight 获取窗口的高度,包括边框和菜单栏等 数值
outerWidth 获取窗口的宽度,包括边框和菜单栏等 数值
pageXOffet 获取窗口从左上角算起水平滚动过的像素数 数值
pageYOffset 获取窗口从左上角算起垂直滚动过的像素数 数值
parent 返回当前Window的父Window Window
postMessage(<msg>,<origin>) 给另一个文档发送消息 void
print() 提示用户打印页面 void
prompt(<msg>, <val>) 显示对话框提示用户输入一个值 字符串
screen 返回一个描述屏幕的Screed象 Screen
screenLeft、ScreenX 获取从窗口左边缘到屏幕左边缘的像素数 数值
screenTop、screenY 获取从窗口上边缘到屏幕上边缘的像素数 数值
scrollBy(<x>, <y>) 让文档相对其当前位置进行滚动 void
scrollTo(<x>, <y>) 滚动到指定的位置 void
self 返回当前文档的Window Window
setInterval(<function>, <time>) 创建一个计时器,每隔time毫秒调用指定的函数 整数
setTimeout(<function>, <time>) 创建一个计时器,等待time毫秒后调用指定的函数 整数
showModalDialog(<url>) 弹出一个窗口,显示指定的URL void
stop() 停止载入文档 void
top 返回最上层的Window Window

下表概述了History对象的成员。

History对象

名称 说 明 返 回
back() 在浏览历史里后退一步 void
forward() 在浏览历史里前进一步 void
go(<index>) 转到相对于当前文档的某个浏览历史位置。正值是前进,负值是后退 void
length 返回浏览历史里的项目数量 数值
pushState(<state>, <title>, <url>) 向浏览器历史添加一个条目 void
replaceState(<state>, <title>, <url>) 替换浏览器历史中的当前条目 void
state 返回浏览器历史里关联当前文档的状态数据 对象

下表概述了Screen对象的成员。

Screen对象

名 称 说 明 返 回
availHeight 返回屏幕上可供显示窗口部分的高度(排除工具栏之类) 数值
availWidth 返回屏幕上可供显示窗口部分的宽度(排除工具栏之类) 数值
colorDepth 返回屏幕的颜色深度 数值
height 返回屏幕的高度 数值
width 返回屏幕的宽度 数值

HTMLElement的成员

HTMLElement对象,它代表了文档里的各种HTML元素。下表概述了此对象定义的成员。

HTMLElement对象

名 称 说 明 返 回
checked 获取或设置checked属性的存在状态 布尔值
classList 获取或设置元素所属类的列表 DOMTokenList
className 获取或设置元素所属类的列表 字符串
dir 获取或设置dir属性的值 字符串
disabled 获取或设置disabled属性的存在状态 布尔值
hidden 获取或设置hidden属性的存在状态 布尔值
id 获取或设置id属性的值 字符串
lang 获取或设置lang属性的值 字符串
spellcheck 获取或设置spellcheck属性的存在状态 布尔值
tabIndex 获取或设置tabindex属性的值 数值
tagName 返回标签名(象征元素的类型) 字符串
title 获取或设置title属性的值 字符串
add(<class>) 给元素添加指定的类 void
contains(<class>) 如果元素属于指定的类则返回true 布尔值
length 返回元素所属类的数量 数值
remove(<class>) 从元素上移除指定的类 void
toggle(<class>) 如果类不存在就添加它,如果存在则移除它 布尔值
attributes 返回应用到元素上的属性 Attr[]
dataset 返回以data-开头的属性 字符串数组[<name>]
getAttribute(<name>) 返回指定属性的值 字符串
hasAttribute(<name>) 如果元素带有指定属性则返回true 布尔值
removeAttribute(<name>) 从元素上移除指定属性 void
setAttribute(<name>, <value>) 应用一个指定名称和值的属性 void
appendChild(HTMLElement) 将指定元素附加为当前元素的子元素 HTMLElement
cloneNode(boolean) 复制某个元素 HTMLElement
compareDocumentPosition(HTMLElement) 判断某个元素的相对位置 数值
innerHTML 获取或设置元素的内容 字符串
insertAdjacentHTML(〈pos〉,<text>) 相对于元素的位置插入HTML void
insertBefore(<newelem>, <childElem>) 将第一个元素插入到第二个(子)元素之前 HTMLElement
isEqualNode(<HTMLElement>) 判断指定元素是否与当前元素等同 布尔值
isSameNode(HTMLElement) 判断指定元素是否就是当前元素 布尔值
outerHTML 获取或设置某个元素的HTML和内容 字符串
removeChild(HTMLElement) 从当前元素上移除指定的子元素 HTMLElement
replaceChild(HTMLElement, HTMLElement) 替换当前元素的某个子元素 HTMLElement
createElement(<tag>) 用指定标签类型创建一个新的HTMLElement对象 HTMLElement
createTextNode(<text>) 用指定内容创建一个新的Text对象 Text

Text对象,它用于代表文档中的文本内容。下表描述了Text对象的成员。

Text对象

名 称 说 明 返 回
appendData(<string>) 在文本块的末尾附加指定字符串 void
data 获取或设置文本 字符串
deleteData(<offset>, <count>) 移除字符串中的文本。第一个数字是偏移量,第二个数字是要移除的字符数量 void
insertData(<offset>, <string>) 在指定的偏移量位置插入指定字符串 void
length 返回字符数量 数值
replaceData(<offset>, <count>, <string>) 用指定字符串替换一部分文本 void
replaceWholeText(<string>) 替换全部文本 Text
splitText(<number>) 将现有的Text元素在指定的偏移量处一分为二。 Text
substringData(<offset>, <count>) 返回文本的子串 字符串
wholeText 获取文本 字符串

DOM里的CSS属性

下表列出了CSSStyleDeclaration对象的属性和它们所对应的样式。

CSSStyleDeclaration对象的成员

成 员 对应于
background background
backgroundAttachment background-attachment
backgroundColor background-color
backgroundimage background-image
backgroundposition background-position
backgroundRepeat background-repeat
border 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 clear
color color
cssFloat float
cursor cursor
direction direction
display display
emptyCells empty-cells
font font
fontFamily font-family
fontSize font-size
FontStyle font-style
fontVariant font-variant
fontweight font-weight
height height
letterSpacing letter-spacing
lineHeight line-height
liststyle list-style
listStylelmage list-style-image
listStylePosition list-style-position
listStyleType list-style-type
margin 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 outline
outlineColor outline-color
outlineStyle outline-style
outlineWidth outline-width
overflow overflow
padding 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 visibility
whitespace whitespace
width width
wordSpacing word-spacing
zIndex z-index

DOM中的事件

DOM的事件系统,有许多不同的事件可供使用,如下表所示。

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 在某张表单被提交时触发
posted @ 2021-10-23 19:08  黄子涵  阅读(136)  评论(0编辑  收藏  举报