4.5 文档对象模型
为了帮助开发者通过编程控制网页上的各种对象,浏览器厂商定义了文档对象模型(DOM),提供了一组可在JavaScript脚本中使用的DOM对象,这些对象都属于宿主对象。
4.5.1 DOM体系结构
基本的DOM体系结构如图4-27所示。
图4-27 基本的DOM体系结构
在浏览器对象模型中,顶层对象是window对象,它表示在浏览器中打开的一个窗口,可以通过它来获取浏览器窗口的状态信息、访问页面元素并处理在浏览器窗口中发生的事件。
screen属性包含客户端屏幕和表现能力的信息的一个对象。screen本身还具有下列属性:availHeight,availWidth,bufferDepth,colorDepth,height,updateInterval,width。通过这些属性可以了解用户显示器的信息,以便动态调整页面布局,获得最佳显示效果。
frames是由给定文档或与某个给定窗口相关联的文档定义的所有window对象的集合。如果HTML文档包含frameset标记,则对于文档中的每个frame标记都有一个window对象。frames有一个length属性,表示框架集包含的框架数目;frames有一个item方法,可以用于访问框架集内的指定框架。当浏览器窗口中包含框架时,为了访问指定框架中的某个文档,必须先访问相应的frame对象,然后才能访问该框架内的文档对象。
history对象包含客户端先前已经访问过的URL的信息。navigator对象包含客户端浏览器的信息。location对象包含关于当前URL的信息。
document对象是window对象的一个重要属性,它表示在浏览器窗口中显示的HTML文档,该对象本身的anchors、forms、images和links等属性是由一些对象组成的集合。
forms是由网页中的所有表单组成的集合。每个表单又包含许多表单控件,例如单行文本框(text)、密码输入框(password)、多行文本框(textarea)、单选按钮(radio)、复选框(checkbox)、列表框(select)、提交按钮(submit)及重置按钮(reset)等。用户可以通过表单控件输入数据并发送到服务器。
4.5.2 window对象
每当在浏览器中打开一个HTML网页时,就会创建一个window对象。若在HTML文档定义了一个或多个框架,则浏览器将为框架页文档创建一个父window对象,然后为每个框架创建一个子window对象。对父window对象进行的操作可以影响各个子window对象。例如,对父window对象调用close方法时,将在关闭父窗口的同时关闭所有子窗口。
在脚本程序中可以访问当前窗口的属性、方法和集合,语法如下:
[oWin.]{property|method(argList)|collection}
其中oWin表示窗口对象,对于当前窗口可以用window或self关键字表示,也可以省略这些关键字。若要对指定的窗口对象进行访问,则必须指定窗口对象。
1.window对象的属性
(1)closed属性。返回引用的窗口是否已经关闭。
(2)defaultStatus属性。指定在浏览器窗口状态栏显示的默认信息。
(3)document属性。返回对document对象的引用,表示在浏览器窗口打开的HTML文档。
(4)event属性。返回表示一个事件状态的对象,通过它可获取事件发生时的键盘按键状态、鼠标位置和鼠标按钮状态。
(5)history属性。返回对history对象的引用,通过该对象可以获取客户端先前已经访问过的URL的信息。
(6)length属性。返回一个窗口包含的框架的数目。
(7)location属性。返回对location对象的引用,通过该对象可以获取当前url的信息。
(8)name属性。指定窗口或框架的名称,以便它可以用做其他文档链接的目标位置。
(9)navigator属性。返回对navigator对象的引用,通过该对象可以获取客户端浏览器的信息。
(10)returnValue属性。指定从网页对话框返回的值,该对话框是用showModalDialog方法创建的。
(11)screen属性。返回对screen对象的引用,通过该对象可获取客户端显示器的信息。
(12)self属性。返回对当前窗口的引用。
(13)status属性。返回或设置浏览器状态栏显示的信息。
2.window对象的方法
(1)alert(message)方法。显示一个警告对话框,包含信息图标、由参数message指定的提示信息和【确定】按钮。
(2)clearInterval(intervalID)方法。取消先前用setInterval方法开始的计时器,该计时器用intervalID参数指定。
(3)clearTimeout(timeoutID)方法。取消一个先前用setTimeout方法设置的计时器,该计时器用intervalID参数指定。
(4)close()方法。用于关闭浏览器窗口。
(5)confirm(message)方法。显示一个确认对话框,包含问题图标、由参数message指定的提示信息、【确定】按钮和【取消】按钮。单击【确定】按钮时返回true;单击【取消】按钮时返回false。
(6)navigate(URL)方法。等价于设置window.location.href属性。
(7)open(URL , name , features, replace)方法。打开一个浏览器窗口并加载由参数URL指定的文档。open方法返回对新窗口的引用。其中name指定新窗口的名称。features指定新窗口的设置,主要特性包括:left和top指定窗口的位置,height和width指定窗口的大小,resizable指定能否改变窗口大小,scrollable指定窗口能否滚动文档内容,toolbar指定是否显示工具栏,status指定是否显示状态栏,location指定是否显示地址栏。
(8)print()方法。打开当前窗口内的文档,相当于选择了【文件】→【打印】命令。
(9)prompt(message, inputDefault)方法。显示一个提示对话框,包含由参数message指定的提示信息、文本框、【确定】按钮和【取消】按钮。单击【确定】按钮时,返回用户在文本框中输入的值。
(10)setInterval(expression, msec)方法。设置一个计时器,经过由msec指定的毫秒数之后重复执行由expression指定的JavaScript语句。
(11)setTimeout(expression, msec)方法。设置一个计时器,经过由msec指定的毫秒数之后执行由expression指定的JavaScript语句。
(12)showModalDialog(URL)方法。创建一个网页对话框并在其中显示由URL参数指定的HTML文档。
3.window对象的事件
(1)onload事件。在浏览器中打开网页时触发该事件。
(2)onresize事件。当调整浏览器窗口大小时触发该事件。
(3)onscroll事件。当在浏览器窗口移动滚动块的位置时触发该事件。
(4)onunload事件。当卸载打开的网页之前触发该事件。
当发生事件时,浏览器会自动查询该事件是否指定了事件处理函数。若指定了事件处理函数,则调用此函数,以完成对事件的响应。若未指定事件处理函数,则什么也不做。
在JavaScript中,事件处理函数可以通过对象的事件句柄来指定。事件句柄可视为对象的一个属性,事件句柄的名称由on加上某个动词构成,例如onload、onclick等。
有以下两种方式可以为对象指定事件处理函数:
● 在HTML标记中把对象的事件句柄属性设置为事件处理函数或语句。
● 在JavaScript脚本中把对象的事件句柄属性设置为命名函数或匿名函数的引用:
function functionName(){ // 定义事件处理函数 body } object.handler=functionName; // 指定命名函数 object.handler=function(){ // 指定匿名函数 body }
其中object表示对象,handler和functionName表示事件句柄和事件处理函数。
例4-25 window对象应用示例。在本例中通过调用window对象的相关方法启用计时器、弹出和关闭窗口,网页运行结果如图4-28所示。
设计步骤
1 在Dreamweaver中打开Ajax站点,在chap04文件夹中创建一个HTML网页并保存为page4-25.html,把网页标题设置为“window对象应用示例”。
图4-28 window对象应用示例
2 在页面上创建两个段落,把第一个段落的id设置为time;在第二个段落中输入“弹出窗口”和“关闭窗口”;选取“弹出窗口”创建一个链接,a元素的id设置为link1,href属性为“#”;取“关闭窗口”创建一个链接,a元素的id设置为link2,href属性为“#”。
3 切换到代码视图,在</title>标记下方创建一个JavaScript脚本块,源代码如下:
<script language="javascript" type="text/javascript"> window.setInterval("var date=new Date(); window.document.getElementById('time').innerHTML=date.getHours()+ ':'+date.getMinutes()+':'+date.getSeconds();",1000) </script>
4 在</body>标记上方创建一个JavaScript脚本块,源代码如下:
<script language="javascript"> var newWin; // 设置两个链接的onclick事件处理程序 link1.onclick=function(){ newWin=window.open('page4-23.html','aa','height=188,width=398,toolbar=no'); } link2.onclick=function(){ if(typeof newWin!="undefined" && !newWin.closed)newWin.close(); self.close(); } </script>
5 在浏览器中查看网页,并对两个链接进行测试。
4.5.3 document对象
document对象表示在浏览器窗口或某个框架中打开的HTML文档,通过该对象可以获取关于该文档的信息,以更改该文档中的HTML元素和文本并对相关事件进行处理。语法如下:
[window.].document.{property|method(argList)}
1.document对象的属性
(1)activeElement属性。标识当前获得焦点的元素。
(2)alinkColor属性。设置或返回文档中活动链接的颜色。
(3)all属性。返回文档所包含的元素集合的引用。
(4)anchors属性。返回文档内所有带有name和/或id属性的a元素组成的数组。
(5)applets属性。返回文档中所有applet对象组成的数组。
(6)bgColor属性。设置或返回文档的背景颜色。
(7)body属性。用来访问HTML文档的body元素。
(8)charset属性。设置或返回HTML文档的字符集。
(9)children属性。获取作为一个元素的直接后代的对象的集合。
(10)cookie属性。指定一个cookie的字符串值,这是由浏览器存储的一条简短信息。
(11)embeds属性。返回文档中所有embed元素组成的数组。
(12)fgColor属性。设置或返回文档中文本的颜色。
(13)forms属性。返回文档中所有form元素组成的数组。
(14)frames属性。返回给定文档或与给定窗口关联的文档定义的所有window对象组成的数组。
(15)images属性。返回文档中所有img元素组成的数组。
(16)lastModified属性。返回当前文档的最后修改日期。
(17)linkColor属性。设置或返回文档中超链接的颜色。
(18)links属性。返回文档中所有指定了href属性的a元素和所有area元素组成的数组。
(19)location属性。设置或返回文档的URL。
(20)parentWindow属性。返回文档的window对象。
(21)readyState属性。返回正在下载的文档的当前状态。
(22)scripts属性。返回文档中所有script元素组成的数组。
(23)selection属性。表示文档中的活动选择,可以是用户或脚本对其进行某些处理的一个高亮度的文本块或其他元素。
(24)styleSheets属性。返回与文档中每个link或style元素的实例相对应的样式表的styleSheet对象组成的数组。
(25)referrer属性。返回导航到当前网页的超链接所在网页的URL。
(26)title属性。设置或返回当前文档的标题。
(27)vlinkColor属性。设置或返回已经访问过的超链接的颜色。
2.document对象的方法
(1)clear()方法。清除当前文档的内容。
(2)close()方法。关闭输出流。
(3)createElement(tag)方法。对特定标记创建一个元素实例,例如,可以用于创建新的img和option元素。
(4)document.createTextNode(string)方法。用指定值创建一个字符串并返回文本节点。
(5)getElementById(id)方法。返回与指定的id属性值匹配的第一个文档元素。id表示要检索的页面元素的id属性。
(6)getElementByName(name)方法。返回name属性与指定的参数值匹配的文档元素组成的数组。name表示文档元素的name属性。
(7)getElementsByTagName(tagName)方法。返回具有指定元素名称的对象数组。
(6)open(mimeType, replace)方法。打开输出流。参数mimeType目前仅支持text/html,replace指示是否替换原内容。
(7)write(string)方法。把参数指定的内容插入到文档的当前位置。string表示要写入文档的HTML代码。
(8)writeln(string)方法。与write方法作用相同,区别是在内容末尾添加一个换行符。
3.document对象的事件
(1)onclick事件。当在网页中单击一个元素时触发。
(2)oncontextmenu事件。当在网页中通过单击鼠标右键打开弹出式菜单时触发。
(3)ondblclick事件。当在网页中双击一个元素时触发。
(4)onkeydown事件。当在一个元素上方按住一个按键不放时触发。
(5)onkeypress事件。当在一个元素上方按下一个按键并释放时触发。
(6)onkeyup事件。当在一个元素上方释放一个按键时触发。
(7)onmousedown事件。当在一个元素上方按下鼠标按钮时触发。
(8)onmousemove事件。当在一个元素上方移动鼠标指针时触发。
(9)onmouseout事件。当鼠标指针离开一个元素时触发。
(10)onmouseover事件。当鼠标指针从一个元素上方经过时触发。
(11)onmouseup事件。在一个元素上方释放鼠标按钮时触发。
例4-26 document对象应用示例。在本例中通过document对象访问页面各种元素并向列表框中动态添加列表项,网页运行结果如图4-29和图4-30所示。
图4-29 在文本框中输入内容并单击按钮
图4-30 添加新的列表项并更新显示
设计步骤
1 在Dreamweaver中打开Ajax站点,在chap04文件夹中创建一个HTML网页并保存为page4-26.html,把网页标题设置为“document对象应用示例”。
2 在页面上输入提示文字,然后添加以下页面元素:
●文本框,将其id设置为txtCourseName;利用【行为】面板将其onkeyup事件处理程序设置为“setAddBtn()”。
● 按钮(<input type="button">),将其id设置为btnAdd,disabled属性设置为disabled,将其onclick事件处理程序设置为“addCourse()”。
● 下拉式列表框,将其id设置为lstCourseName。
● 在该下拉式列表框右边添加一个<span>标记,将其id设置为spnCount。
3 切换到代码视图,在</title>下方创建一个JavaScript脚本块,源代码如下:
<script language="javascript" type="text/javascript"> function setAddBtn(){ var btnAdd=document.getElementById("btnAdd"); var txtCourseName=document.getElementById("txtCourseName"); btnAdd.disabled=(txtCourseName.value==""?"disabled":""); } function addCourse(){ var txtCourseName=document.getElementById("txtCourseName"); var btnAdd=document.getElementById("btnAdd"); var spnCount=document.getElementById("spnCount"); var lstCourseName=document.getElementById("lstCourseName"); var count=lstCourseName.options.length; var option=document.createElement("option"); option.value=txtCourseName.value; option.text=txtCourseName.value; lstCourseName.options[count]=option; spnCount.innerHTML="(共包含 "+(count+1).toString().bold()+" 门课程)"; txtCourseName.value=""; txtCourseName.focus(); btnAdd.disabled="disabled"; } </script>
4 在浏览器中查看网页,并对表单控件的功能进行测试。
4.5.4 navigator对象
navigator对象用于检测浏览器的版本信息、所支持的MIME类型,以及已安装的外挂程序(plug-in)等。语法如下:
[window.]navigator.{property|method()}
1.navigator对象的属性
(1)appCodeName属性。表示浏览器的代码名称。Navigator、Internet Explorer都返回Mozilla,不能通过该信息来区分不同的浏览器。
(2)appName属性。返回浏览器应用程序的官方名称。对于Netscape浏览器,该属性值为Netscape;对于Internet Explorer浏览器,值为Microsoft Internet Explorer。
(3)appVersion属性。返回浏览器的版本信息。对于Internet Explorer 6.0,该属性的值为:4.0 (compatible;MSIE 6.0; Windows NT 5.1; SV1)。
(4)language属性。返回浏览器应用程序的语言代码。
(5)mimeType属性。以对象数组形式返回浏览器支持的MIME类型。
(6)platform属性。返回运行浏览器的操作系统类型。
(7)plugins属性。以对象数组形式返回已安装的外挂程序。
(8)userAgent属性。返回用户代理程序的标头。
(9)userLanguage属性。返回当前用户所使用的语言。
2.navigator对象的方法
(1)javaEnabled()方法。返回一个Boolean值,指示浏览器是否支持Java。该方法的返回值随浏览器的参数设置而变。
(2)preference()方法。用于设置浏览器的首选项。
4.5.5 location对象
location对象包含当前URL的信息。语法如下:
[window.]location.{property|method([argList])}
1.location对象的属性
(1)href属性。返回或设置当前文档的完整URL。
(2)hash属性。返回或设置当前URL中“#”后面的部分,也就是书签的名称。
(3)host属性。返回或设置当前URL中的主机名和端口部分。
(4)hostname属性。返回或设置当前URL中的主机名。
(5)port属性。返回或设置当前URL中的端口部分。
(6)pathname属性。返回或设置当前URL中的路径部分。
(7)protocol属性。返回或设置当前URL中的协议类型。
(8)search属性。返回或设置当前URL中跟在问号后面的查询字符串。
2.location对象的方法
(1)reload()方法。重新加载当前网页。
(2)replace(URL)方法。用指定的URL刷新当前网页。
4.5.6 history对象
history对象包含用户已经浏览过的URL集合,提供了类似浏览器导航按钮的功能。语法如下:
[window.]history.{property|method}
history对象的length属性用于返回历史列表中的URL数目。
history对象具有以下方法。
(1)back()方法。加载历史列表中后退一个URL的网页。
(2)forward()方法。加载在历史列表中向前一个URL的网页。
(3)go(n)方法。加载历史列表中第n个URL的网页。n>0表示前进,n<0表示后退。
4.5.7 W3C DOM节点处理
W3C是World Wide Web Consortium的缩写,通常译为万维网联盟。W3C成立于1994年10月,该组织专门致力于创建Web相关技术标准并促进Web向更深、更广发展。W3C负责DOM进行标准化,目前这项工作尚未最终完成,W3C DOM标准也没有被所有浏览器实现。下面介绍W3C DOM的层次及DOM节点的类型、属性和方法。
1.DOM层次
W3C对DOM定义了以下4个层次。
(1)DOM Level 0。该层次并不是W3C的标准,它仅仅是对Netscape Navigator 3.0和Internet Explorer 3.0相关功能的界定,习惯上称为标准JavaScript对象模型。该层次是DOM中HTML部分的起始点,提供了使用已有脚本代码在符合W3C DOM标准的浏览器上工作的方法,支持公用的文档集合,包括forms、images、anchors、links和applets。
(2)DOM Level 1。该层次是在DOM Level 0基础上建立起来的,其主要目标是定义HTML和XML文档模型,它包含了文档导航和文档操作的性能,并提供了一组公用函数集,用于访问所有页面元素。W3C于1998年10月将DOM Level 1列为推荐的版本。
(3)DOM Level 2。提供了访问包含XML和CSS在内的页面元素的功能,并提供了更高级的事件模型。该层次尚未完全被主流浏览器支持。W3C于2000年11月将DOM Level 2列为推荐的版本。
(4)DOM Level 3。W3C于2004年4月提出了DOM Level 3推荐标准。迄今为止,还没有哪个浏览器完全实现该标准,只有Mozilla部分实现了该标准。
2.DOM节点的类型
在W3C DOM中,用节点来描述HTML或XML文档中的元素。W3C DOM Level 2定义了12种节点类型(见表4-10),其中有6种类型与HTML关联,有一些节点类型只与XML关联。
表4-10 DOM节点的类型
3.DOM节点的属性
(1)nodeName属性。获取节点的名称,其值为字符串。随节点类型而变化。
(2)nodeValue属性。获取节点的值,其值为字符串。随节点的类型而变化。
(3)nodeType属性。获取节点的类型,其值为整数。
(4)ownerDocument属性。获取与节点相关联的Document对象。
(5)childNodes属性。获取HTML元素和文本节点对象的数组。
(6)firstChild属性。获取对childNodes数组中第一个子节点的引用。
(7)lastChild属性。获取对childNodes数组中最后一个子节点的引用。
(8)parentNode属性。获取文档层次中的父节点。
(9)previousSibling属性。返回对父节点的前一个子节点(即兄弟节点)的引用。若当前节点就是第一个兄弟节点,则该属性值为null。
(10)nextSibling属性。返回对下一个兄弟节点的引用。若当前节点就是最后一个兄弟节点,则该属性值为null。
(11)attributes属性。获取元素节点的属性的数组。
4.DOM节点的方法
(1)hasChildNodes()方法。返回一个Boolean值,指示该节点是否包含子节点。如果childNodes集合包含一个或多个节点,则返回true,否则返回false。
(2)appendChild(node)方法。把节点node追加到childNodes数组末尾。
(3)removeChild(node)方法。从childNodes数组中移除node节点。
图4-31 DOM节点操作示例
(4)replaceChild(newNode, childNode)方法。把childNodes数组中的childNode节点替换为newNode节点。
(5)insertBefore(newNode [, childNode])方法。在childNodes数组中的childNode节点之前插入newNode节点。
例4-27 DOM节点操作示例。在本例中通过调用DOM提供的相关方法实现节点的添加、修改和删除操作,网页运行结果如图4-31所示。
设计步骤
1 在Dreamweaver中打开Ajax站点,在chap04文件夹中创建一个HTML网页并保存为page4-27.html,把网页标题设置为“DOM节点操作示例”。
2 在页面中创建一个文本段落,并输入提示文字;添加一个文本框,并将其id设置为txtContent;添加一个按钮,并将其id设置为btnAddNode,type属性设置为button,value属性设置为“添加节点”,利用【行为】面板将其onclick事件处理程序设置为“AddNode()”。
3 创建第二个段落,在该段落中添加两个按钮,并将其id分别设置为btnModifyNode和btnDeleteNode,value属性分别设置为“修改节点”和“删除节点”,type属性均为button;利用【行为】面板将这两个按钮的onclick事件处理程序分别设置为“modifyNode()”和“deleteNode()”。
4 切换到代码视图,在</title>标记下方创建CSS样式表,源代码如下:
<style type="text/css"> <!-- body,input{font-size:9pt;} body{text-align:center;} --> </style>
5 在</style>标记下方创建一个JavaScript脚本块,源代码如下:
<script language="javascript" type="text/javascript"> function addNode(){ var text=document.getElementById("txtContent").value; if(text==""){ window.alert("需要输入文本内容。"); document.getElementById("txtContent").focus(); return; } var pNode=document.createElement("p"); var textNode=document.createTextNode(text); pNode.appendChild(textNode); document.body.appendChild(pNode); } function modifyNode(){ var oldPNode=document.body.getElementsByTagName("p")[2]; if(oldPNode){ var text=document.getElementById("txtContent").value; if(text=="" || text==oldPNode.innerText){ window.alert("需要输入文本内容。"); document.getElementById("txtContent").focus(); return; } var newPNode=document.createElement("p"); var textNode=document.createTextNode(text); newPNode.appendChild(textNode); oldPNode.parentNode.replaceChild(newPNode,oldPNode); }else{ window.alert("指定的节点目前不存在。"); } } function deleteNode(){ var pNode=document.body.getElementsByTagName("p")[2]; if(pNode){ if(!window.confirm("您确实要删除这个节点吗?"))return; pNode.parentNode.removeChild(pNode); }else{ window.alert("指定的节点目前不存在。"); } } </script>
6 在浏览器中打开网页,并对各个按钮的功能进行测试。