文档对象模型与事件驱动
文档对象模型(DOM)是一个基础性的概念,主要涉及网页页面的元素的层次关系。理解文档对象模型的概念,对于编写出高效、实用的JavaScript程序非常有帮助的。而事件和事件处理是网页设计中必须面对的问题,也就是使网页变得多姿多彩的重要手段。
文档对象模型(DOM)是表示文档和访问、操作构成文档的各种元素的应用程序接口(API)。
DOM是一种与浏览器、平台、语言无关的接口,使得用户可以访问页面其他标准组件。
DOM是以层次结构组织的节点或信息片段的集合。这个层次结构允许开发人员在树立导航寻找特定的信息。分析该结构通常需要加载整个文档和构造层次结构,才能做任何工作。
JavaScript使用浏览器对象模型(BOM) 和文档对象模型(DOM)两种主要模型。
图1
动态改变文档的背景色:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
function changeBgclr(value) {
document.body.style.backgroundColor = value;
}
</script>
</head>
<body >
<form>
<input type="radio" value="red" onclick="changeBgclr(this.value)"/>红色
<input type="radio" value="green" onclick="changeBgclr(this.value)"/>绿色
<input type="radio" value="blue" onclick="changeBgclr(this.value)"/>蓝色
</form>
</body>
</html>
图2
- 访问节点
在DOM中,HTML文档各个节点被视为各种类型的Node对象。每个Node对象都有自己的属性和方法,利用这些属性和方法可以遍历整个文档树。由于HTML文档的复杂性,DOM定义了nodeType来表示节点的类型。
节点是某个网络中的一个连接点,即网络是节点和连线的集合。在W3C DOM中,每个容器、独立的元素或文本块都可以看做是一个节点,节点是W3C DOM的基本构建元素。当一个容器包含另一个容器时,其对应的节点存在着父子关系。同时该节点树遵循HTML的结构化本质,如元素包含、,而前者又包含,后者包含各种块元素等。DOM定义了HTML文档中6中不同的节点类型。<br/> DOM节点树中的节点有三种不同的类型:<br/> ① :元素节点
<ul id="booklist">
<li>洗衣机</li>
<li>冰箱</li>
<li>电视机</li>
</ul>
② :文本节点(提供内容)
③ :属性节点
<h1 class="Sample">go to DOM World!</h1>
<ul id="booklist">...</ul>
class和Sample都属于属性节点
- 节点的基本操作:
① :创建节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>创建并验证节点</title>
<script type="text/javascript">
function nodeStatus(node) {
var temp = "";
if(node.nodeName != null){
temp += "nodeName: " + node.nodeName + "\n";
}
else temp += "nodeName :null\n";
if(node.nodeType!=null)
{
temp += "nodeType: " + node.nodeType + "\n";
}
else temp += "nodeType :null\n";
if(node.nodeValue != null){
temp += "nodeValue: " + node.nodeValue + "\n";
}
else temp += "nodeValue :null\n";
return temp;
}
function test(){
//产生P元素节点和新文本节点
var newParagraph = document.createElement("p"); //创建一个含P元素的新节点
var newTextNode = document.createTextNode(document.MyForm.MyField.value); //创建一个内容为Text的文本节点
var msg = nodeStatus(newParagraph); //msg为新创建的节点
msg += nodeStatus(newTextNode); //将新创建的节点赋给msg
alert(msg);
return;
}
</script>
</head>
<body >
<form name="MyForm">
<input type="text" name="MyField" id="MyField" value="Text" />
<input type="button" value="测试" onclick="test()"/>
</form>
</body>
</html>
浏览器显示的结果为:
图3
在生成节点后,要将节点添加到DOM树中。
② :插入和添加节点
将新创建的节点插入到文档的节点树中的最简单的方法就是,让它成为该文档某个现有节点的子节点,appendChild(newChild)作为要添加子节点的节点方法被调用,在该节点的子节点列表的结尾添加一个newChild。其语法格式为object.appendChild(newChild)。
可以使用appendChild()方法将下面两个节点连接起来。
newNode = document.createElement("b");
newText = document.createTextNode("welcome to xi'an");
newNode.appendChild(newText);
经过appendChild()方法结合后,则会得到如下结果:
<b>welcome to xi'an</b>
就可以将其插入到文档中的合适位置,如可以插入到某个段落的结尾:
current = document.getElementById("p1");
对于nodeType的解释:
nodeType是用来获得当前节点对象的类型。
如果节点是元素节点,则 nodeType 属性将返回 1。
如果节点是属性节点,则 nodeType 属性将返回 2。
元素element 1
属性attr 2
文本text 3
在文本节点的后边插入新的节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>在节点树中插入节点</title>
<script type="text/javascript">
function nodeStatus(node) {
var temp = "";
if(node.nodeName!=null){
temp += "nodeName : " + node.nodeName + "\n";
}else temp += "nodeName : null\n";
if(node.nodeType!=null){
temp += "nodeType: " + node.nodeType + "\n";
}else temp += "nodeType : null\n";
if(node.nodeValue!=null){
temp += "nodeValue : " + node.nodeValue + "\n\n";
}else temp += "nodeValue:null\n\n";
return temp;
}
function Mytest() {
//产生P元素节点和新文本节点,并将文本节点添加为P元素节点的最后一个子节点
var newParagraph = document.createElement("p"); //创建一个含P元素的新节点
var newTextNode = document.createTextNode(document.MyForm.MyField.value); //创建一个内容为Text的文本节点
newParagraph.appendChild(newTextNode);
var msg = nodeStatus(newParagraph); //调用nodeStatus()函数创建了P元素的节点
msg += nodeStatus(newTextNode); //调用nodeStatus()函数创建了P+Value元素的节点,这个时候的内容已经发生了改变
msg += nodeStatus(newParagraph.firstChild); //调用nodeStatus()函数创建了P元素的一个孩子,孩子包含之前父节点的信息。
alert(msg);
return ;
}
</script>
</head>
<body >
<form name="MyForm">
<input type="text" name="MyField" value="Text" />
<input type="button" value="测试" onclick="Mytest()"/>
</form>
</body>
</html>
在网页中显示的结果为:
图4
在文本节点的前面插入新的节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>在节点树中插入节点</title>
</head>
<body >
<p id="p1">go to<B>DOM</B>World!</p>
<script type="text/javascript">
function nodeStatus(node) {
var temp = "";
if(node.nodeName!=null){
temp += "nodeName : " + node.nodeName + "\n";
}else temp += "nodeName : null\n";
if(node.nodeType!=null){
temp += "nodeType: " + node.nodeType + "\n";
}else temp += "nodeType : null\n";
if(node.nodeValue!=null){
temp += "nodeValue : " + node.nodeValue + "\n\n";
}else temp += "nodeValue:null\n\n";
return temp;
}
//输出节点树相关信息
//返回id属性值为p1的元素节点
var parentElement = document.getElementById("p1");
var msg = "insertBefore方法之前:\n";
msg += nodeStatus(parentElement);
//返回p1的第一个孩子,即文本节点Welcome to
var targetElement = parentElement.firstChild;
msg += nodeStatus(targetElement);
//返回文本节点Welcome to的下一个同父节点,即元素节点B
var currentElement = targetElement.nextSibling;
msg += nodeStatus(currentElement);
//返回元素节点P的最后一个孩子,即文本节点“World!”
currentElement = parentElement.lastChild;
msg += nodeStatus(currentElement);
//生成新文本节点Please,并插入到文本节点go to之前
var newTextNode = document.createTextNode("Please");
parentElement.insertBefore(newTextNode,targetElement);
msg += "insertBefore方法之后:\n" + nodeStatus(parentElement);
//返回p1的第一个孩子,即文本节点Please
targetElement = parentElement.firstChild;
msg += nodeStatus(targetElement);
//返回文本节点go to 的下一个同父节点,即元素节点go to
var currentElement = targetElement.nextSibling;
msg += nodeStatus(currentElement);
//返回元素节点P,即文本节点“World!”
currentElement = parentElement.lastChild;
msg += nodeStatus(currentElement);
alert(msg); //输出节点属性
function insertAfter(newChild,targetChild)
{
var parentElement = targetChild.parentNode;
//检查目标节点是否是父节点的最后一个节点
//是:直接按appendChild()方法插入新节点
if(parentElement.lastChild==targetChild)
{
parentElement.appendChild(newChild);
}
//不是:使用目标节点的nextSibling属性定位到下一同父节点,按insertBefore()方法操作
else
parentElement.insertBefore(newChild,targetElement.nextSibling);
}
</script>
</body>
</html>
在网页中显示的结果为:
图5
DOM本身并没有提供insertBefore()函数,但是我们可以通过自己编写代码来实现功能:
function insertAfter(newChild,targetChild)
{
var parentElement = targetChild.parentNode;
//检查目标节点是否是父节点的最后一个节点
//是:直接按appendChild()方法插入新节点
if(parentElement.lastChild==targetChild)
{
parentElement.appendChild(newChild);
}
//不是:使用目标节点的nextSibling属性定位到下一同父节点,按insertBefore()方法操作
else
parentElement.insertBefore(newChild,targetElement.nextSibling);
}
③ :复制节点并将其插入到节点树中:
复制分为复制和深度复制,只有深度复制的时候,才能实现真正的复制:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>复制节点</title>
</head>
<body >
<p id="p1">Please <em>go to </em>DOM World</p>
<hr>
<div id="inserthere" style="background-color: blue;"></div>
<hr>
<script type="text/javascript">
function cloneAndCopy(nodeId,deep){
var toClone = document.getElementById(nodeId); //复制
var clonedNode = toClone.cloneNode(deep); //深度复制
var insertPoint = document.getElementById("inserthere");
insertPoint.appendChild(clonedNode); //添加节点
}
</script>
<form action="#" method="get">
<!--通过设置cloneAndCopy()第二个参数为true或false来控制复制的结果-->
<input type="button" value="复制" onclick="cloneAndCopy('p1',false);"/>
<input type="button" value="深度复制" onclick="cloneAndCopy('p1',true);"/>
</form>
</body>
</html>
网页显示结果为:
先看原效果:
图6
点击复制之后的效果:
图7
点击深度复制之后的效果:
图8
所以深度复制时,是复制了节点自身以及节点所有的子节点。
④ :删除节点和替换节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>删除和替换节点</title>
<script type="text/javascript">
function doDelete() {
var deletePoint = document.getElementById('toDelete'); //标记要删除的节点
if(deletePoint.hasChildNodes()) //如果含有子节点
deletePoint.removeChild(deletePoint.lastChild); //移除最后子节点
}
function doReplace() {
var replace = document.getElementById('toReplace'); //标记要替换的节点
if(replace) //如果目标存在
{
//创建新节点的元素属性
var newNode = document.createElement("strong");
var newText = document.createTextNode("strong element");
//执行追加操作
newNode.appendChild(newText);
//执行替换操作
replace.parentNode.replaceChild(newNode,replace);
}
}
</script>
</head>
<body >
<div id="toDelete" align="center">
<p>This is node</p>
<p>This is <em>another node</em> to delete</p>
<p>This is yet another node</p>
</div>
<p align="center">
This node has an <em id="toReplace">em element</em>in it.
</p>
<hr>
<form action="#" method="get">
<!--通过onclick事件,调用相应的删除与替换函数,完成任务-->
<input type="button" value="删除" onclick="doDelete()" />
<input type="button" value="替换" onclick="doReplace()"/>
</form>>
</body>
</html>
原效果图为:
图9
点击删除之后(不同的浏览器DOM树中包含空白字符,所以需要多点击几次):
图10
再点击替换:
图11
⑤ :修改节点
虽然元素属性可以修改,但是元素不能被直接修改。如果要进行修改,需要改变节点本身。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>修改节点</title>
</head>
<body >
<p id="p1">Welcome to xi'an</p>
<script type="text/javascript">
//调用并存储p1节点的第一个子节点的相关属性
var textNode = document.getElementById('p1').firstChild;
</script>
<form action="#" method="get">
<!--通过调用onclick()事件,对节点进行修改、追加、插入、删除、替换等操作-->
<input type="button" value="显示" onclick="alert(textNode.data);"/>
<input type="button" value="长度" onclick="alert(textNode.length);"/>
<input type="button" value="改变" onclick="textNode.data = 'nice to meet you!'"/><p>
<input type="button" value="追加" onclick="textNode.appendData(' too');"/>
<input type="button" value="插入" onclick="textNode.insertData(0,'very ');"/>
<input type="button" value="删除" onclick="textNode.deleteData(0,2);"/><p>
<input type="button" value="替换" onclick="textNode.replaceData(0,4,'tel');"/>
<!--调用substringData()来读取子串-->
<input type="button" value="子串" onclick="alert(textNode.substringData(2,2))" />
<!--调用splitText()来完成拆分操作-->
<input type="button" value="拆分" onclick="temp = textNode.splitText(5); alert('Text node = ' + textNode.data+'\nSplit Value = ' + temp.data);"/>
</form>
</body>
</html>
网页中显示的结果为:
图12
- 文档对象模型的属性和方法:
在DOM中,文档对象有许多初始属性,可以是一个单词、数值或数组,来自产生对象的HTML标记的属性设置。如果标记没有显示设置属性,浏览器默认使用默认值来给标记的属性和相应的JavaScript文本属性赋值。在DOM中,文档所有的组成部分都被看做是树的一部分,文档中所有的元素都是树的节点(Node),每个节点都是一个Node对象,每种Node对象都定义了特定的属性和方法。
firstChild和LastChild指向当前标记的子节点集合内的第一个和最后一个子节点,但是在多数情况下使用childNodes集合,用循环遍历子节点。如果没有子节点,则childNodes的长度为:0。
如:
<p id="p1">
welcome to
<B> xi'an</B>
lanZhou
</p>
在上段代码中,我们可以总结出如下知识:
图13
- 事件处理:
事件和事件处理时网页设计中必须面对的问题,也是网页多姿多彩的必需手段。在一个Web网页中,浏览器可以通过调用JavaScript来响应用户的操作。当用户点击某个超链接,或者编辑表单域中的内容时,浏览器就会调用相应的JavaScript代码。在此过程中,JavaScript响应的操作就是事件。事件将用户和Web页面连接在一起,使用户之间可以交互,以响应用户的操作。
事件由浏览器动作(如浏览器载入文档)或用户动作(诸如敲击键盘、滚动鼠标等)触发,而事件处理程序则说明一个对象如何响应事件。
事件不仅仅局限于鼠标和键盘操作,也包括浏览器状态的改变,如绝大部分浏览器支持类似resize和load这样的事件等。load事件在浏览器载入文档时被触发。如果某事件要在文档载入时被触发,一般应该在标记中加入语句 onload = “MyFunction()”。而resize 事件在用户改变浏览器窗口的大小时触发。在用户改变窗口大小时,有时需要改变文档页面的内容布局,从而使其以恰当、友好的方式显示给用户。
事件可以发生在很多场合,包括浏览器本身的状态和页面的按钮、链接、图片、层等。同时根据DOM模型,文本也可以作为对象,并响应相关的动作,如点击鼠标、文本被选择等。事件的处理方法甚至结果同浏览器的环境都有很大的关系,浏览器的版本越新,所支持的事件处理器就越多,支持也就越完善,所以在编写JavaScript脚本时,要充分考虑浏览器的兼容性,才可以编写出合适多数浏览器的安全脚本。 - 常见的事件驱动:
JavaScript是基于对象的语言,而Java是面向对象的语言。而基于对象的基本特征,就是采用事件驱动(Event-driven)。它是在用户图形界面的环境下,使得一切输入变得简单化。通常鼠标或热键的动作称为事件(Event),而对事件处理的程序或函数,我们称为事件处理程序。
JavaScript事件驱动中的事件是通过鼠标或热键的动作引发的。它主要有如下几个事件:
① :单击事件onclick()
② :改变事件onCange()
③ :选中事件onSelect()
④ :获得焦点事件onFocus()
⑤ :失去焦点onBlur()
⑥ :载入文件onLoad()
⑦ :卸载文件onUnload() - JavaScript处理事件的方式:
尽管HTML事件属性可以将事件处理器绑定为文本的一部分,但其代码一般较为短小,功能也比较弱,适用于只需要做简单的数据验证、返回相关提示信息等场合。使用JavaScript脚本可以更为方便地处理各种事件。
① 匿名函数:通过Function对象构造匿名函数,并将其方法复制给事件,此时匿名函数就成为改事件的事件处理器。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body >
<center>
<br>
<p>通过匿名函数处理事件</p>
<form name="MyForm" id="MyForm">
<input type="button" name="MyButton" id="MyButton" value="测试"/>
</form>
<script type="text/javascript">
document.MyForm.MyButton.onclick = new Function()
{
alert("已经单击该按钮!");
}
</script>
</center>
</body>
</html>
网页显示的效果为:
图14
图片翻转事例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>通过使用鼠标交换图片</title>
<script type="text/javascript">
function MyImageA(){
document.all.MyPic.src = "images/demo1.jpg";
}
function MyImageB(){
document.all.MyPic.src = "images/demo2.jpg";
}
</script>
</head>
<body >
<center>
<p>在图片内外移动鼠标,图片轮转</p>
<img name="MyPic" id="MyPic" src="images/demo1.jpg" width="300" height="200"/>
<script type="text/javascript">
document.all.MyPic.onmouseover = MyImageA;
document.all.MyPic.onmouseout = MyImageB;
</script>
</center>
</body>
</html>
鼠标在图片内:
图15
鼠标在图片外:
图16
② 手工触发:手工触发处理事件的元素很简单,即通过其他元素的方法来触发一个事件,而不是通过用户的动作来触发事件。如果某个对象的事件有其默认的处理器,此时再设置该事件的处理器时,就可能出现意外的情况。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
<title>使用手工触发的方式处理事件</title>
<script type="text/javascript">
function MyTest(){
var msg = "通过不同的方式返回不同的结果: \n\n";
msg += "单击【测试】按钮,即可直接提交表单\n";
msg += "单击【确认】按钮即可触发onsubmit()方法,然后才提交表单\n";
alert(msg);
}
</script>
</head>
<body >
<br>
<center>
<form name="MyForm1" id="MyForm1" onsubmit="MyTest()" method="post" action="happyt.asp">
<input type="button" value="测试" onclick="document.all.MyForm1.submit();"/>
<input type="submit" value="确定" />
</form>
</center>
</body>
</html>
这段代码中,因为现在还未涉及到后台的知识,所以测试方面的效果是无法实现的,在网页中显示的结果为:
图17
单击确认按钮之后,还是会弹出相应的对话框:
图18
- 使用event对象:
JavaScript的event对象用来描述JavaScript的事件,event代表事件状态,如事件发生的元素、键盘状态、鼠标位置和鼠标按钮状态。一旦事件发生,便会生成event对象,如单击一个按钮,浏览器的内存中就产生相应的event对象。
实例:通过事件控制文本框的背景颜色
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>文本框获得焦点时改变背景颜色</title>
</head>
<script type="text/javascript">
function txtfocus (event){
var e = window.event;
var obj = e.srcElement;
obj.style.background = "#F00066";
}
function txtblur(event) {
var e = window.event;
var obj = e.srcElement;
obj.style.background = "#FFFFF0";
}
</script>
<body >
<table border="0" align="center" width="360" height="228">
<tr>
<td width="188">登录名称:</td>
<td width="226">
<form action="" method="post" name="form1">
<input type="text" name="textfield" onfocus="txtfocus()" />
</form>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<form name="form2" action="" method="post">
<input type="text" name="textfield2" onfocus="txtfocus()" onblur="txtblur()" />
</form>
</td>
</tr>
<tr>
<td>姓名:</td>
<td>
<form name="form3" action="" method="post">
<input type="text" name="textfield3" onfocus="txtfocus()" onblur="txtblur()" />
</form>
</td>
</tr>
<tr>
<td>性别:</td>
<td>
<form name="form4" action="" method="post">
<input type="text" name="textfield5" onfocus="txtfocus()" onblur="txtblur()" />
</form>
</td>
</tr>
<tr>
<td>联系方式:</td>
<td>
<form name="form5" action="" method="post">
<input type="text" name="textfield4" onfocus="txtfocus()" onblur="txtblur()" />
</form>
</td>
</tr>
</table>
</body>
</html>
两个函数,一个是聚焦时实现改变背景色,一个是离开时返回到原先的背景颜色。
在网页中显示的结果为:
图19
实例:在DOM模型中获得对象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>解析HTML对象</title>
<script type="text/javascript">
window.onload = function(){
//通过document.documentElement获取根节点
var zhwHtml = document.documentElement;
alert(zhwHtml.nodeName); //打印节点名称HTML大写
var zhwBody = document.body; //获取body标签节点
alert(zhwBody.nodeName); //打印Body节点的名称
var fH = zhwBody.firstChild; //获取body的第一个子节点
alert(fH + "body的第一个子节点");
var lH = zhwBody.lastChild; //获取body的最后一个子节点
alert(lH + "body的最后一个节点");
var ht = document.getElementById("zhw"); //通过ID获取<h1>
alert(ht.nodeName);
var text = ht.childNodes;
alert(text.length);
var txt = ht.firstChild;
alert(txt.nodeName);
alert(txt.nodeValue);
alert(ht.innerHTML);
alert(ht.innerText + "Text");
}
</script>
</head>
<body >
<h1 id="zhw">我是一个内容节点</h1>
</body>
</html>
在网页中显示的结果为:
图20
实例:超级链接的事件驱动
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>JavaScript事件驱动</title>
<script type="text/javascript">
function countTotal(){
var elements = document.getElementsByTagName("input");
window.alert("input类型节点总数为:" + elements.length);
}
function anchorElement(){
var element = document.getElementById("submit");
window.alert("按钮的Value是:" + element.value);
}
</script>
</head>
<body >
<table width="364" border="1" cellspacing="0" cellpadding="0">
<form action="" name="form1" method="post">
<tr>
<td width="20%"> 用户名</td>
<td width="80%"> <input type="text" name="input1" value=""></td>
</tr>
<tr>
<td> 密码</td>
<td> <input type="password" name="password1" value=""></td>
</tr>
<tr>
<td> </td>
<td> <input type="submit" id="submit" value="提交"></td>
</tr>
</form>
<a href="javascript:void(0);" onclick="countTotal();">统计input子节点总数</a>
<a href="javascript:void(0);" onclick="anchorElement();">获取提交按钮内容</a>
</table>
</body>
</html>
在网页中显示的结果为:
单击统计input子节点总数后:
单击获取提交按钮内容后:
图21
处理对象和文档对象
JavaScript除了可以访问本身内置的各种对象外,还可以访问浏览器提供的对象。通过对这些对象的访问,可以得到当前网页及浏览器本身的一些信息,并能完成有关的操作。
- 窗口(window)对象
window对象在客户端JavaScript中扮演着重要的角色,它是客户端程序的全局(默认)对象,还是客户端对象层次的根。它是JS中最大的对象。它描述的是一个浏览器的窗口,一般要引用其属性和方法时,不需要用window XXX这种形式,而是直接使用XXX。一个框架页面也是一个窗口。window对象表示浏览器中打开的窗口。
举例:关闭窗口
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>window属性</title>
</head>
<body >
<script type="text/javascript">
function shutwin(){
window.close();
return ;
}
</script>
<a href="javascript:shutwin();">关闭本窗口</a>
</body>
</html>
在这个例子中,当点击了“关闭本窗口”这个超链接之后,就会触发close()函数,并关闭这个窗口。
图22
- window对象的属性
一个HTML文档至少有一个window对象,如果某个网页有多帧,则会有多个window对象。
① defaultStatus 属性:
状态条信息。
② document属性:
获取当前显示的文档
③ 框架属性集:
窗口框架(frameElement)
例子:
js.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>含有窗口框架的网页</title>
</head>
<frameset rows="60, *" cols="*" frameborder="1" border="1" framespacing="1">
<frame src="top.html" name="topFrame" scrolling="no" id="top" marginheight="0" marginwidth="0" noresize/>
<frame src="main.html" name="mainFrame" scrolling="auto" id="main" >
</frameset>
</html>
main.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
<title>窗口框架</title>
<script type="text/javascript">
function getFrame()
{
//获取当前窗口所在的框架
var frameObj = window.frameElement;
window.alert("当前窗口所在框架的名称: " + frameObj.name);
window.alert("当前窗口的框架数量: " + window.length);
}
function openWin()
{
//打开一个窗口
window.open("top.html","_blank");
}
</script>
</head>
<body >
<form name="frmData" method="post" action="#">
<input type="hidden" name="hidObj" id="hidObj" value="隐藏变量" />
<p>
<center>
<h1>显示框架页面的内容</h1>
</center>
</p>
<p>
<center>
<input type="button" value="窗口框架" onclick="getFrame()" />
</center>
<br>
<center>
<input type="button" value="打开窗口" onclick="openWin()" />
</center>
</p>
</form>
</body>
</html>
top.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
<title>顶部框架页面</title>
</head>
<body >
<form name="frmTop" method="post" action="#">
<center>
<h1>框架顶层页面</h1>
</center>
</form>
</body>
</html>
网页显示的结果为:点击“窗口框架”之后
图23
点击“打开窗口”之后:
图24
④ history属性:
history对象提供用户最近浏览过的URL列表。在一个会话中,用户早些时候访问过的页面相关信息是保密的,因此,在脚本中不允许直接查看显示过的URL。
⑤ parent属性:
当使用框架时,多数情况下想要同时使用多个框架。
实例:多个框架
js.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>含有窗口框架的网页</title>
</head>
<frameset rows="60, *" cols="*" frameborder="0" border="0" framespacing="0">
<frame src="top.html" name="topFrame" scrolling="no" id="top" marginheight="0" marginwidth="0" noresize/>
<frameset cols="200,*" frameborder="1" framespacing="2" marginwidth="0" marginheight="0" leftmargin="0" topmargin="0">
<frame src="left.html" name="leftFrame" target="mainFrame" scrolling="auto" bordercolor="#FBFBFB" id="left"/>
<frame src="right.html" name="mainFrame" scrolling="auto" id="main" />
</frameset>
</frameset>
</html>
top.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
<title>顶部框架页面</title>
</head>
<body >
<form name="frmTop" method="post" action="#">
<center>
<h1>框架顶层页面</h1>
</center>
</form>
</body>
</html>
left.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
</head>
<body >
<form name="frmTop" method="post" action="#">
<center>
<h1>框架左层页面</h1>
</center>
</form>
</body>
</html>
right.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8"/>
</head>
<body >
<form name="frmTop" method="post" action="#">
<center>
<h1>框架右层页面</h1>
</center>
</form>
</body>
</html>
页面显示的效果为:
图25
- 对话框
对话框的作用就是与浏览者进行交流,有提示、选择和获取信息的功能。JavaScript提供了三种标准的对话框,分别是弹出对话框、选择对话框和输入对话框。这三种对话框都是基于window对象产生的,即作为window对象的方法使用的。
alert() ——提示信息
confirm() ——确认信息
prompt() ——输入信息
例子:alert
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>提示框</title>
<script type="text/javascript">
window.alert("提示信息");
function showMsg(msg){
if(msg == "简介") window.alert("提示信息:简介");
window.status = "显示本站的" + msg;
return true;
}
window.defaultStatus = "欢迎光临本网站";
</script>
</head>
<body>
<form name="frmData" method="center" border="1" cellspacing="0">
<table border="1" cellspacing="0" border="1" align="center" width="400">
<thead>
<th colspan="3">在线购物网站</th>
</thead>
<script type="text/javascript">
window.alert("加载过程中的提示信息");
</script>
<tr>
<td valign="top" width="200">
<ul>
<li><a href="#" onmouseover="return showMsg('主页')">主页</a></li>
<li><a href="#" onmouseover="return showMsg('简介')">简介</a></li>
<li><a href="#" onmouseover="return showMsg('联系方式')">联系方式</a></li>
<li><a href="#" onmouseover="return showMsg('业务介绍')">业务介绍</a></li>
</ul>
</td>
<td valign="top" width="300">
上网购物是一种新的购物理念
</td>
</tr>
</table>
</form>
</body>
</html>
最终显示结果为:
当鼠标放在简介上面时:
图26
例子:confirm
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>alert方法与confirm方法进行比较</title>
<script type="text/javascript">
function destory() {
if(confirm("确定关闭该网站吗?")) //confirm()方法用作判断条件
alert("是的,我确定关闭此网页");
else alert("您选择的是不关闭网页!")
}
</script>
</head>
<body>
<div align="center">
<h1>alert()方法与confirm()方法</h1>
<hr>
<form action="#" method="get">
<!--通过onclick调用destory()函数-->
<input type="button" value="确定" onclick="destory();" />
</form>
</div>
</body>
</html>
网页显示结果为:
图27
prompt方法 实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>prompt</title>
<script type="text/javascript">
function askGuru(){
var question = prompt("请输入内容?","");
if(question != null){
if(question == "") alert("您还没有输入内容!");
else alert("输入成功!");
}
}
</script>
</head>
<body>
<div align="center">
<h1>prompt方法使用实例</h1>
<hr>
<br>
<form action="#" method="get">
<!--通过onclick调用askGuru()函数-->
<input type="button" value="确定" onclick="askGuru()"/>
</form>
</div>
</body>
</html>
网页显示效果为:
图28
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>打开新窗口</title>
</head>
<body onload="setWindowStatus()">
<script type="text/javascript">
function setWindowStatus()
{
window.status = "Window对象的简单应用实例,这里的文本是由status属性设置的。";
}
function NewWindow(){
msg = open("","DisplayWindow","toolbar=no,directories=no,menubar=no");
msg.document.write("<head><title>新窗口</title></head>")
msg = document.write("<center><h2>这是由Window对象的open方法打开的新窗口!</h2></center>");
}
</script>
<input type="button" name="Button1" id="Button1" value="打开新窗口" onclick="NewWindow();"/>
</body>
</html>
在网页中显示的结果为:
图29
- 文档对象(document)
分别写几段代码实例来介绍一些比较常用到的知识:
① 设置页面各个颜色的初始值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>综合应用Document对象中的颜色属性</title>
<script type="text/javascript">
//设置文档的颜色显示
function SetColor(){
document.bgColor = "yellow";
document.fgColor = "green";
document.linkColor = "red";
document.alinkColor = "blue";
document.vlinkColor = "purple";
}
//改变文档的背景颜色为海蓝色
function ChangeColorOver(){
document.bgColor = "navy";
return;
}
//改变文档的背景色为黄色
function ChangColorOut(){
document.bgColor = "yellow";
return;
}
</script>
</head>
<body onload="SetColor()">
<center>
<br>
<p>设置颜色</p>
<a href="#">链接颜色</a>
<form name="MyForm3">
<input type="submit" name="MySure" id="MySure" value="动态背景图" onmouseover="ChangeColorOver()" onmouseout="ChangColorOut()"/>
</form>
</center>
</body>
</html>
网页显示效果为:
图30
原始效果为背景图是黄色,当鼠标放在“动态背景图上面时,就会发生颜色的变化”
② 获取锚点数组大小
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>文档中的锚点</title>
<script type="text/javascript">
function getAnchors(){
var anchorAry = document.anchors; //得到锚点数组
window.alert("锚点数组大小: " + anchorAry.length);
for(var i = 0; i<anchorAry.length; i++)
{
window.alert("第" + (i+1) + "个锚点是:" + anchorAry[i].name);
}
}
</script>
</head>
<body>
<form name="frmData" method="post" action="#">
<center>
<ul>
<li><a href="#linkName" name="whatLink">电子商务</a></li>
<li><a href="#" name="colorLink">时尚服饰</a></li>
</ul>
</center>
<br>
<p><input type="button" value="锚点数组" onclick="getAnchors()" /></p>
<br>
<p></p>
<p>
<a name="linkName">电子商务</a>
<br>
电子商务通常是指……
</p>
<a href="#whatLink">返回</a>
</form>
</body>
</html>
网页显示效果为:
图31
③ 获取文档中的窗体:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>文档中的表单</title>
<script type="text/javascript">
function getWin()
{
window.alert("窗体的长度:" + document.forms.length);
window.alert("窗体中隐藏域的值:" + document.frmData.hidField.value);
window.alert("使用名称数组得到的隐藏域的值:" + document.forms["frmData"].hidField.value);
}
</script>
</head>
<body>
<form name="frmData" method="post" action="#">
<input type="hidden" name="hidField" id="hidField" value="123" />
<input type="button" value="得到窗体" onclick="getWin()" />
</form>
</body>
</html>
网页中显示的效果为:
图32
- 文档中的表单和图片
一个HTML文档中的每个标记都会在Document对象的Forms[]数组中创建一个元素,同样,每个标记也会创建一个images[]数组的元素。同时,这一规则还适用于和标记,它们分别对应于Links[]和applet[]数组的元素。
例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>document属性使用</title>
</head>
<body>
<div>
<h2>在文本框中输入内容,注意第二个文本框变化:</h2>
<form>
内容:<input type="text" onchange="document.my.elements[0].value=this.value;" />
</form>
<form name="my">
结果:<input type="text" onchange="document.forms[0].elements[0].value=this.value;" />
</form>
</div>
</body>
</html>
网页中显示的效果为:
图33
在此例中,触发onchange()函数来得到输入的信息。通过数组来得到内容。
实例:综合使用各种对话框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script type="text/javascript">
function display_alert()
{
alert("我是弹出对话框");
}
function disp_prompt()
{
var name = prompt("请输入名称","");
if(name!=null && name!=""){
document.write("你好" + name + "!");
}
}
function disp_confirm()
{
var r = confirm("按下按钮");
if(r==true)
{
document.write("单击确认按钮");
}
else
document.write("单击返回按钮");
}
</script>
</head>
<body>
<input type="button" onclick="display_alert()" value="弹出对话框" />
<input type="button" onclick="disp_prompt()" value="输入对话框" />
<input type="button" onclick="disp_confirm()" value="选择对话框" />
</body>
</html>
效果图就不展示了。
实例:设置弹出的窗口
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>打开新窗口</title>
<script type="text/javascript">
function openWin(){
var _url = "index.html"; //指定URL
var _name = "_blank"; //指定打开窗口的名称
var _feature = ""; //打开窗口的效果
var _left = (window.screen.width-400)/2; //计算新窗口居中时距离屏幕左边的距离
var _top = (window.screen.height-300)/2; //计算新窗口居中时距离屏幕上方的距离
_feature += "left=" + _left + ","; //新窗口距离屏幕左边的距离
_feature += "top=" + _top + ","; //新窗口距离屏幕上方的距离
_feature += "width=500,"; //新窗口的宽度
_feature += "height=400"; //新窗口的高度
_feature += "resizable=0,"; //大小不可更改
_feature += "scrollbars=1,"; //滚动条显示
_feature += "menubar=0,toolbar=0,status=0,location=0,directories=0";
var win = window.open(_url,_name,_feature);
}
</script>
</head>
<body>
<form name="frmData" method="post" action="#">
<table width="600" align="center" border="1" cellspacing="0">
<thead>
<th colspan="3">网上购物</th>
</thead>
<tr>
<td valign="top" width="200">
<ul>
<li><a href="#" onmousemove="return showMsg('主页')">主页</a></li>
<li><a href="#" onmousemove="return showMsg('简介')">简介</a></li>
<li><a href="#" onmousemove="return showMsg('联系方式')">联系方式</a></li>
<li><a href="#" onmousemove="return showMsg('业务介绍')">业务介绍</a></li>
</ul>
</td>
<td valign="top" width="300">
上网是一种新的消费理念
</td>
</tr>
<tr align="center">
<td colspan="3" align="center">
<input type="button" value="打开新窗口" onclick="openWin()"/>
</td>
</tr>
</table>
</form>
</body>
</html>
这里边有一段代码是来规定新窗口的位置的:
var _name = "_blank"; //指定打开窗口的名称
var _feature = ""; //打开窗口的效果
var _left = (window.screen.width-400)/2; //计算新窗口居中时距离屏幕左边的距离
var _top = (window.screen.height-300)/2; //计算新窗口居中时距离屏幕上方的距离
_feature += "left=" + _left + ","; //新窗口距离屏幕左边的距离
_feature += "top=" + _top + ","; //新窗口距离屏幕上方的距离
_feature += "width=500,"; //新窗口的宽度
_feature += "height=400"; //新窗口的高度
_feature += "resizable=0,"; //大小不可更改
_feature += "scrollbars=1,"; //滚动条显示
_feature += "menubar=0,toolbar=0,status=0,location=0,directories=0";
如果没有这段代码,新窗口就会显示在新的网页中。这段代码的作用就是在此网页中显示新的窗口,就像弹出了一个新的对话框一样。
网页显示结果为:
图34
JavaScript的调试和错误处理
当JavaScript引擎执行JavaScript代码时,会发生各种错误:可能是语法错误,可能是拼写错误或语言中缺少的功能;可能是由于来自服务器或用户的错误输入而导致的错误。等等。
处理异常的方法:
onerror事件处理异常:
try-catch-finally语句处理异常:
throw语句抛出异常:
JavaScript和Ajax技术
Ajax能使浏览器为用户提供更为自然的浏览体验,就像在使用桌面应用程序一样。
- Ajax的关键元素:
JavaScript
CSS
DOM
XMLHTTPRequest
其中最新颖的就是XMLHTTPRequest,Ajax利用一个构建到所有现代浏览器内部的XMLHTTPRequest对象来实现发送和接收HTTP请求与响应信息。一个经由XMLHTTPRequest对象发送的HTTP请求并不要求页面中拥有或回发一个元素。
实例:加载条
首先这是一个动态的效果,利用Ajax来实现此功能的关键在于加载条从0%到100%。从0%开始,每50ms自加1一次加一条判断,如果加到了101%,就不显示101%,跳转到“完毕!”并结束。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>加载条</title>
<style type="text/css">
.load_{
width: 200px;
height: 40px;
padding: 20px 50px;
margin: 20px;
font-size: 9pt;
background: #eee;
}
.load_p{
margin-bottom: 8px;
height: 12px;
line-height: 12px;
border: 1px solid;
border-color: #fff #000 #000 #fff;
padding: 4px 2px 2px;
text-align: right;
font-size: 7pt;
font-family: "Lucida Sans!important ";
color: #333;
background: #ff0;
}
</style>
</head>
<body>
<div class="load_">
<p style="width: 1%;" id="load_"></p>
正在载入,请稍后……
</div>
<script type="text/javascript">
function $(id,tag){
if(!tag)
{
return document.getElementById(id);
} else {
return document.getElementById(id).getElementsByTagName(tag);
}
}
function loads_(obj,s)
{
var objw = $(obj).style.width;
if(objw!="101%")
{
if(!s) {var s=0;}
$(obj).innerHTML=objw;
$(obj).style.width=s+"%";
s++;
setTimeout(function (){loads_(obj,s)},50);
}
else {
$(obj).innerHTML="完毕!";
}
}
loads_("load_");
</script>
</body>
</html>
网页中显示的效果为:
图35