JavaScript是一种解释语言,使用它可以使你的网页制作得更加科学、生动和美观,人-机界面更加友好。本章将提供大量的程序实例介绍JavaScript的基本概念和应用,为读者进一步深入学习JavaScript和其他描述性语言打下基础。 除了19.10节和19.11节中的部分源程序,本章所示的程序都是在Netscape公司的Communicator 4.04浏览器和微软公司的Internet Explorer 3.0以上版本的浏览器上运行过的,如果使用Netscape公司和微软公司较低版本的浏览器时,有可能会出现异常。
19.1 简介
JavaScript不是Java! 由于JavaScript与Java类似,而且它们的名称也很相似,JavaScript又支持大多数Java表示法和基本的流程控制结构,因此许多人都认为JavaScript就是Java。其实,JavaScript是由客户机解释的语言,而Java是从服务机上下载在客户机上运行的编译过的字节码(bytecodes);JavaScript的对象是在运行时引用的,称为动态联编(Dynamic binding),而Java的对象是编译时引用的,称为静态联编(Static binding)。 JavaScript是由Netscape公司开发的一种脚本语言(scripting language),或者称为描述语言。在HTML基础上,使用JavaScript可以开发交互式Web网页。运行用JavaScript编写的程序需要能支持JavaScript语言的浏览器。Netscape公司Navigator 3.0以上版本的浏览器都能支持JavaScript程序,微软公司Internet Explorer 3.0以上版本的浏览器基本上支持JavaScript。微软公司还有她自己开发的JavaScript,称为JScript。JavaScript和JScript有许多相似之处。 在介绍过程中,将通过大量的例子来体会JavaScript的含义,这些例子与HTML紧紧地连在一起,并且可以直接应用于网页制作。由于例子中的每条语句、每个对象和每个符号等许多细节不可能在本书中详细阐述。因此,如果需要更深入更详细的内容,请参看有关JavaScript语言和HTML语言方面的参考文献。
19.2 事件与函数
19.2.1 HTML文档中嵌入JavaScript
JavaScript程序可直接嵌入到HTML文档中,如下例所示: <HTML> <HEAD> <TITLE>JavaScript入门</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- JavaScript程序开始 - document.write("这是JavaScript!") // - JavaScript结束 - --> </SCRIPT> </HEAD> <BODY> <P>这是JavaScript程序</P> </BODY> </HTML> 在这个例子中,我们可看到在<HEAD> … </HEAD> 之间插入了一个新的标签:<SCRIPT> … </SCRIPT>,而<SCRIPT LANGUAGE="JavaScript">用来告诉浏览器这是用JavaScript编写的程序。HTML的注释标签<!-- 和 -->用来告诉浏览器不要显示注释
19.2.2 事件的概念
在JavaScript语言中,事件(events)和事件处理程序(event handlers)是非常重要的事情。绝大部分事件都是由用户的动作所引发的。如果用户按鼠标器的按钮,就产生Click(点击)事件,如果鼠标器的指针在链接上移动,就产生MouseOver事件。在JavaScript中定义有许多事件。要使JavaScript程序能够响应事件,就需要事件处理程序的帮助。当点击按钮时,按钮可创建一个弹出窗口,我们需要使用的事件处理程序就叫做ONCLICK。如果出现按钮事件,事件处理程序就告诉计算机做什么工作。例如,下面所示的源程序: <FORM> <INPUT TYPE="BUTTON" VALUE="点击该按钮" ONCLICK="alert('哈哈!')"> </FORM> 在浏览器上将显示如图19-01和图19-02所示的页面。
点击该按钮之后产生→  图19-01 事件概念(一) 图19-02 事件概念(二)
在这个源程序中,<INPUT>标签中的TYPE=" BUTTON " VALUE="点击改按钮" 这部分产生一个按钮 ,ONCLICK="alert('哈哈!')"这部分告诉计算机在有点击事件出现后要执行alert( ' 哈哈!')程序,alert()将创建一个弹出窗口,括号中指定的是字符串,本例中是'哈哈!',这是要在窗口上显示的文字。执行程序的结果是产生一个窗口,并显示“哈哈!”。 在ONCLICK="alert('哈哈!')"这部分中用了单引号(' ')和双引号(" ")。这两种引号都可以使用,次序也可以颠倒,即可写成ONCLICK='alert("哈哈!") '。 在JavaScript中有许多事件处理程序可用,但不包含所有的事件处理程序。如果需要全面了解,请参看JavaScript的参考手册。
19.2.3 函数的概念
在JavaScript中,函数(Function)是一个很重要的概念。函数实际上是把几个命令捆绑在一起的子程序。由于历史的原因,现在许多中文教科书都把“Function”叫做函数,但其实质是“函数例程”。 假如我们要写一段重复输出相同文本三次的程序,下面是一种完成这个功能的源程序: <HTML> <SCRIPT LANGUAGE="JavaScript"> <!-- hide document.write("JavaScript不是很难学!<br>"); document.write("这是JavaScript!<br>"); document.write("JavaScript不是很难学!<br>"); document.write("这是JavaScript!<br>"); document.write("JavaScript不是很难学!<br>"); document.write("这是JavaScript!<br>"); // --> </SCRIPT> </HTML> 这段程序在浏览器上将显示如图19-03所示的页面。
 图19-03 演示函数概念的页面
完成同样功能的这段源程序也可以用下面的程序来实现: <HTML> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function myFunction() { document.write("JavaScript不是很难学!<br>"); document.write("这是JavaScript!<br>"); } myFunction(); myFunction(); myFunction(); // --> </SCRIPT> </HTML> 在这段程序中我们定义了一个函数: function myFunction() { document.write("JavaScript不是很难学!<br>"); document.write(这是JavaScript!<br>"); } 其中,function是JavaScript函数的声明语句,function后面跟的函数名“myFunction”可以是任意的名字,myFunction函数的命令放在大括号“{ }”中,该函数捆绑了两个JavaScript的“document.write()”命令,并且可通过函数调用来执行。在这个例子中可以看到,在函数定义下面调用函数myFunction()共3次。 函数也可以与事件处理程序联用。例如, <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function calculation() { var x= 12; var y= 5; var result= x + y; alert(result); } // --> </SCRIPT> </HEAD> <BODY> <FORM> <INPUT TYPE="BUTTON" VALUE="计算" ONCLICK=" calculation()"> </FORM> </BODY> </HTML> 其中,关键字“var”是JavaScript的变量(variable)声明语句,声明“x”、“y”和“result”是变量;<INPUT … >这条语句表示,当点击标有“计算”字样的BUTTON按钮时就调用函数calculation()。你可以把这段程序存放在一个名为fuc_test.html文件中,然后用浏览器试一试,看计算结果是否等于17。
19.3 层次结构
19.3.1 JavaScript的层次结构
JavaScript以分层结构的方式组织Web网页上的所有文素。每个文素都被作为一个对象(Object)来看待,称为“HTML对象”,每个对象都有属性(Properties)和处理法(methods)。下面是一个简单的HTML文档,存放该文档的文件名假设为jstest.html: <HTML> <HEAD> </HEAD> <BODY BGCOLOR="#FFFFFF"> <CENTER><IMG SRC="image(0).gif" WIDTH=126 HEIGHT=115> </CENTER><P> <FORM ID="MyForm"> 姓名: <INPUT TYPE="TEXT" NAME="name" VALUE=""><BR><BR> email: <INPUT TYPE="TEXT" NAME="email" VALUE=""><BR><BR> <INPUT TYPE="BUTTON" VALUE="请按此按钮" NAME="myButton" ONCLICK="location.href='../../../www./default.htm'; "> </FORM><P> <CENTER> <IMG SRC="image(1).gif" WIDTH=400 HEIGHT=10><BR><BR> <A HREF="http://166.111.34.216/">我的主页</A> </CENTER> </BODY> </HTML> 在浏览器上将显示如图19-04所示的页面。
 图19-04 层次结构分析页面
从JavaScript的功能来看,Web浏览器本身是一个窗口对象(window object),在这个对象中可以加载HTML文档,例如jstest.html。同样,JavaScript把jstest.html也看成是一个对象,称为文档对象(document object),它也是JavaScript中的一个非常重要的对象,而且会经常用到它。 在jstest.html这个HTML文档中,有两幅图像(image[0],image[1])、一个链接(links[0])以及一个交易单(form),交易单中带有两个文本域(element[0],element[1])和一个按钮(element[3])。它们的结构如图19-05所示。
 图19-05 JavaScript的层次结构
JavaScript把图19-05中的每个框都看成是对象。如果要想得到各种不同对象的信息和管理它们,首先我们就要知道这些对象的名称,其次我们必须要知道如何去存取这些对象。图19-01为我们给各个对象的命名提供了很大的启发,就是按照JavaScript的层次结构来命名。据此,可按照从顶向下的路线,第一个对象就被命名为“document”,第一幅图像被命名为“document.images[0]”,…,第一个交易单中的第一个文本对象被命名为“document.forms[0].elements[0]”,…,document.forms[0].elements[3]。 为了得到各种对象的属性和可使用的处理法,我们必须要查看有关JavaScript的文献(请看参考文献:JavaScript参考手册)。例如,我们查看“text”(文本)对象时,可以看到它有很多属性(property)和可使用的处理法(method)。其中的一个属性是值(value),这个值是输入到这个对象的文本,于是我们就可使用下面的格式存取对象的值: name= document.forms[0].elements[0].value; 我们可把forms[0]的名称命名为"myForm",于是“input”对象1的名称就可写成"document.myForm.input",它的属性是value,而“对象2”和“对象3”就可对“对象1”进行操作。例如, <FORM name="myForm"> 对象1: <INPUT TYPE="TEXT" NAME="input" VALUE="原来的数据"><p> 对象2: <INPUT TYPE="BUTTON" VALUE="更新数据" ONCLICK="document.myForm.input.value= '新的数据!'; "> <p> 对象3: <INPUT TYPE="BUTTON" VALUE="恢复数据" ONCLICK="document.myForm.input.value= '原来的数据!'; "> </FORM> 在浏览器上将显示如图19-06所示的页面。
 图19-06 对象间的操作
点击“更新数据”按钮就对“对象1”进行操作,显示“新的数据!”。
19.3.2 网址对象
除了window(窗口对象)和document(文档对象)之外,另一个重要的对象是location(网址对象)。这个对象代表的是要访问的HTML文档所在的网络地址。因此,如果你要访问网页http://www./page.html,那么location.href就等于这个网址。 更重要的是你可以给location.href指定新的值。下面的例子就可以把新的网页加载到窗口上: <FORM > <INPUT TYPE="BUTTON" VALUE="中国教育和科研计算机网(CERNET)" ONCLICK="location.href='../../../www./default.htm'; "> </FORM> 在浏览器上将显示如图19-07所示的页面。
 图19-07 网址对象的演示页面
当你点击该按钮时就可浏览“中国教育和科研计算机网”的主页。
19.4 帧窗
19.4.1 创建帧窗
也许你浏览万维网(Web)时已经注意到,Web浏览器窗口被分成两个或者三个显示窗口,分别显示各自的HTML文档。每个这样的小窗口称为frame,可把它译成“帧窗”。一个常见的问题就是JavaScript如何与帧窗一起工作。 创建帧窗需要使用<frameset>和</frameset>标签。例如要把Web浏览器窗口分成两个等宽的帧窗,可用下面的程序实现: <HTML> <FRAMESET ROWS="50%,50%"> <FRAME SRC="page1.html" NAME="frame1"> <FRAME SRC="page2.html" NAME="frame2"> </FRAMESET> </HTML> 在浏览器上将显示如图19-08所示的页面。
 图19-08 创建帧窗的概念
在这个程序中使用了<frameset>的rows(行)属性把Web浏览器窗口分成上下两个帧窗,上面的帧窗加载page1.html,下面的帧窗加载page2.html。 如果使用<frameset>的columns(列)属性,Web浏览器窗口就会被纵向分割。此外,浏览器窗口的分割还可以嵌套。例如,使用下面的程序可在横向和纵向对浏览器窗口进行分割: <FRAMESET ROWS="50%,50%"> <FRAMESET COLS="50%,50%"> <FRAME SRC="page1.html"> <FRAME SRC="page2.html"> </FRAMESET> <FRAMESET COLS="33%,33%,33%"> <FRAME SRC="page3.html"> <FRAME SRC="page4.html"> <FRAME SRC="page5.html"> </FRAMESET> </FRAMESET> 在浏览器上将显示如图19-09所示的页面。
 图19-09 创建不同样式的帧窗
19.4.2 JavaScript和帧窗
前面已经介绍,JavaScript以分层结构的方式来组织网页上的所有文素,对帧窗也是如此。为了简单起见,假设Web浏览器窗口被分成frame1和frame2两个帧窗,在这种情况下的分层结构如图19-10所示:
 图19-10 两个帧窗的结构
顶层是browser window(浏览器窗口)对象,称为parent(父窗口),下层是frame1(帧窗1)和frame2(帧窗2)对象,称为children(子帧窗)。通过对这些对象进行命名之后在两个帧窗之间就可以交换信息。例如,用户在frame1上点击一个链接,本来应该是在frame1显示的HTML文档,现在可让它显示在frame2上。这样一来,frame1就可以作为浏览目录,目录中的每个条目就可以链接到许多不同站点的主页。 图19-11所示的网页是帧窗的一个具体应用。在这个应用中,帧窗frame1作为“多媒体技术基础”作业的目录项,帧窗frame2用来显示具体内容。例如,在frame1中点击“详细内容”时,在frame2中显示作业的详细内容,而帧窗frame1的内容保持不变。
 图19-11 一个帧窗作为浏览目录的网页
设计这样的网页首先需要一个创建frame1和frame2两个帧窗的程序,在此假设程序名为jstest02.html,这个程序可写成: <HTML> <FRAMESET COLS="25%,75%"> <FRAME SRC="menu.html" NAME="menu"> <FRAME SRC="homework.html" NAME="main"> </FRAMESET> </HTML> 在这个程序中,把frame1命名为menu,开始时显示menu.html文档;把frame2命名为main,开始时显示homework.html文档。
homework.html: <HTML> <HEAD></HEAD> <BODY> <CENTER>大学本科生基础课程<BR> <H2>“多媒体技术基础”</H2><BR> 作业式样<BR> (仅供参考)<BR> </CENTER> </BODY> </HTML> menu.html: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function load(url) { parent.main.location.href= url; } // --> </SCRIPT> </HEAD> <BODY> <PRE> <A HREF="homework.html" TARGET="main">多媒体技术基础</A></PRE> <A HREF="start.html" TARGET="main">作业名称</A><BR> <A HREF="javascript::load('first.html')">内容简介 </A><BR> <A HREF="second.html" TARGET="main">影视图像</A><BR> <A HREF="third.html" TARGET="_top">作业总结</A><BR> </BODY> </HTML> menu.html文档涉及如下所示的4个文档: ① start.html文档: <HTML> <BODY> <CENTER><U>开始页</U><BR> <H2>作业名称</H2> … </CENTER> </BODY> </HTML> ② first.html文档: <HTML> <BODY> <CENTER><U>文档1</U><BR> <H2>内容简介</H2></CENTER> </BODY> </HTML> ③ second.html: <HTML> <BODY> <CENTER><U>文档2</U><BR> <H2>影视片段</H2></CENTER> </BODY> </HTML> ④ third.html: <HTML> <BODY> <CENTER><U>文档3</U><BR> <H2>学习总结</H2></CENTER> </BODY> </HTML> 在menu.html文档中,需要说明如下几点: (1) 使用了一种把新的网页加载到main帧窗中的不同方法。具体说就是,在“<A HREF="javascript:load('first.html')">内容简介 </A><BR>”中的链接使用了加载函数load(),并且在<A>的属性HREF=" "中使用了“javascript:”来把first.html文档加载到main帧窗中。 (2) JavaScript的加载函数load()定义为: function load(url) { parent.main.location.href= url; } 括号“( )”中的url是传递参数的变量,这就意味字符串'first1.html'通过url变量来传递。通过变量来传递参数是程序设计的一个重要概念。 (3) 其他链接使用的是标签“<A>”的“TARGET”属性,实际上它不是JavaScript的属性,而是HTML的属性。 (4) 在“<A HREF="third.html" TARGET="_top">作业总结</A>”中,“<A>”的属性“TARGET=_top”是去掉frame1和frame2帧窗。third.html将显示在整个浏览器窗口中。 (5) 如果浏览器窗口分割成frame1、frame2和frame3共三个帧窗,使用JavaScript的load()函数可能会更灵活,此时的load()函数可定义为: function loadtwo(url1, url2) { parent.frame1.location.href= url1; parent.frame2.location.href= url2; } 然后你可用loadtwo("first.htm", "second.htm") 或者loadtwo("third.htm", "forth.htm")来调用这个函数。
9.5 创建新窗口与建立新文档
19.5.1 创建新窗口加载HTML文档
打开一个新的浏览器窗口是JavaScript的一个重要特性。创建窗口使用window.open()命令。下面是一个打开新窗口并把HTML文档(例如21_lecture.html)加载到新窗口的程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function openWin1() { myWin=window.open("21_lecture.html"); } // --> </SCRIPT> </HEAD> <BODY> <FORM> <INPUT TYPE=SUBMIT VALUE="打开新窗口+新文档" ONCLICK="openWin1()"> </FORM> </BODY> </HTML> 运行该程序后在浏览器窗口中显示 ,点击该按钮后就可把你创建的21_lecture.html文档加载到一个新的浏览器窗口,而原来的窗口仍然存在。
19.5.2 window.open()的处理法
在函数window.open中,它的处理法(method)可有3种选择参数,可以用来指定窗口显示的内容、窗口的名称和外观。这3个参数是: ① 指定要加载的HTML文档的URL。例如,21_lecture.html。 ② 窗口的名称。“displayWindow”是所有Web浏览器都支持的名称。有些浏览器可使用你自己喜欢的名称,例如“MyWindow”。 ③ 一套窗口外观参数选项(options)。例如,窗口的宽度、高度、滚动框和其他功能。 window.open ()的一般处理法格式为: newwindow=window.open("mypage.html","mywindow", options) 例如,要把21_lecture.html文档加载到一个宽度(width)为400象素、高度(height)为300象素的浏览器窗口,窗口中没有状态(status)栏、没有工具栏(toolbar)和选单栏(menubar),创建这种窗口可以写出如下所示的程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!--hide function openWin2() { myWin=open("21_lecture.html", "displayWindow", "width=400,height=300,status=no,toolbar=no,menubar=no"); } // --> </SCRIPT> </HEAD> <BODY> <FORM> <INPUT TYPE=SUBMIT VALUE="打开指定新窗口" ONCLICK="openWin2()"> </FORM> </BODY> </HTML> 请注意:①在字符串"width=400,height=300,status=no,toolbar=no,menubar=no"中没有空格字符;②myWin是变量,而不是window的名称。表19-01列出了可供选择的参数选项。
表18-01 窗口参数选项
窗口属性 |
yes/no |
directories(显示目录栏) |
yes/no |
height(设置窗口高度) |
象素值 |
location(显示文档地址框) |
yes/no |
menubar(显示选单栏) |
yes/no |
resizable(设置窗口缩放) |
yes/no |
scrollbars(设置滚动框) |
yes/no |
status(设置状态栏) |
yes/no |
toolbar(设置工具栏) |
yes/no |
width(设置窗口宽度) |
象素值 |
19.5.3 创建新窗口与建立新文档
JavaScript的一个很时髦特性是可以在创建的新窗口中创建HTML文档以及VRML(Virtual Reality Modeling Language)文档。下面是创建一个简单的HTML文档的程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function openWin3() { myWin= open("", "displayWindow", "width=500,height=400,status=yes,toolbar=yes,menubar=yes"); //打开文档准备后面的输出 myWin.document.open(); // 创建文档而不是打开新窗口 myWin.document.write("<HTML><HEAD><TITLE>创建新的HTML文档"); myWin.document.write("</TITLE></HEAD><BODY>"); myWin.document.write("<CENTER><FONT SIZE=+1>"); myWin.document.write("用JavaScript创建HTML文档"); myWin.document.write("</FONT></CENTER>"); myWin.document.write("</BODY></HTML>"); // 关闭文档而不是窗口 myWin.document.close(); } // --> </SCRIPT> </HEAD> <BODY> <FORM> <INPUT TYPE=SUBMIT VALUE="创建新的HTML文档" ONCLICK="openWin3()"> </FORM> </BODY> </HTML> 在这个程序中,函数winOpen3()用来创建一个新的浏览器窗口。winOpen3()中的第一个参数是空字符串,这表示JavaScript没有指定URL,也就是不加载已经编写好的HTML文档,而是要创建一个新文档。 在这个程序中定义了一个变量myWin,借助该变量而不是窗口名(displayWindow)去访问这个新窗口。在打开这个新窗口之后,通过使用文档对象(document object)的open()处理法,即通过myWin.document.open()来为后面的输出作准备。myWin必须放在document.open()之前,以便访问这个新窗口。下面是使用document.write()处理法创建文档: myWin.document.write("<HTML><HEAD><TITLE>创建新的HTML文档"); myWin.document.write("</TITLE></HEAD><BODY>"); myWin.document.write("<CENTER><FONT SIZE=+1>"); myWin.document.write("用JavaScript创建HTML文档"); myWin.document.write("</FONT></CENTER>"); myWin.document.write("</BODY></HTML>"); 在创建HTML文档之后需要用myWin.document.close()关闭文档。
19.6 状态栏和超时设置
19.6.1 状态栏设置
JavaScript程序可通过设置窗口的状态属性window.status对Web浏览器底部的状态栏进行写入操作。下面是在状态栏上写入“'Hi! 这是状态栏”和清除状态的程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function statbar(txt) { window.status = txt; } // --> </SCRIPT> </HEAD> <BODY> <FORM> <INPUT type="button" NAME="look" VALUE="写入!" ONCLICK="statbar('Hi! 这是状态栏!');"> <INPUT type="button" NAME="erase" VALUE="清除!" ONCLICK="statbar('');"> </FORM> </BODY> </HTML> 在这个程序中创建了有 和 按钮的交易单,它们都调用了函数statbar(),而且在括号中指定了字符串“'Hi! 这是状态栏!”和空字符串。这表明,这些字符串是与函数 statbar()一起传递到状态栏上的,因为在程序中定义该函数名时在括号中使用了“txt”作为变量。在程序设计中,给函数传递变量是经常使用的方法,这样可使函数变得更灵活。 在状态栏上写入文字可很方便地为用户提示状态信息。例如,当用户把鼠标器的指针指到带有链接的对象时,在状态栏上就可以显示被链接网页的URL地址。下面的程序就是一个这样的例子。 <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function statbar(txt) { window.status = txt; } // --> </SCRIPT> </HEAD> <BODY> <A HREF="http://www." onMouseOver="window.status='连接 http:/www.'; return true;" onMouseOut="window.status='';">中国教育和科研计算机网(CERNET)</A> </BODY> </HTML> 在浏览器上将显示如图19-12所示的页面。
 图19-12 状态栏的设置和显示
虽然浏览器本身的默认设置是当你把鼠标器的指针移到超文本链接时,状态栏上会显示URL目的地址,但如果要在状态栏上显示其他内容时,你就可以使用onMouseOut和onMouseOver事件处理程序来设置。使用这两个处理程序时必须要使用“return true”。
19.6.2 定时设置
超时设置程序(timeout)也称定时器(timer),使用它可让计算机在超过一定的时间之后执行某种程序。下面是一个当你点击按钮之后3秒钟会弹出一个窗口。 <SCRIPT LANGUAGE="JavaScript"> <!-- hide function timer() { setTimeout"alert('从点击按钮开始算起时间已超过3秒钟!')", 3000); } // --> </SCRIPT> ... <FORM> <INPUT type="button" VALUE="定时器" ONCLICK="timer()"> </FORM> 在浏览器上将显示如图19-13所示的页面。
 图19-13 定时设置演示
在这个程序中,setTimeout()是window对象的处理法。setTimeout()中的第一个参数是JavaScript的程序,在这个例子中是"alert('从点击按钮开始算起时间已超过3秒钟!')",它将显示一个带有消息和OK按钮的对话框;第二个参数是告诉计算机什么时候要执行这个程序,你可以指定定时的时间,时间单位用毫秒。
19.6.3 滚动程序
在了解如何设置状态栏和定时器之后,我们可看看浏览器状态栏上的滚动文本是如何实现的,这是在因特网上经常都可看到的。实现滚动文本的程序称为滚动程序(scroller),下面是它的源程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide //定义要滚动的文本 var scrtxt = "这是JavaScript! " + "这是JavaScript! " + "这是JavaScript!"; var length = scrtxt.length; //文本的长度 var width = 100; //文本滚动框的宽度 var pos = -(width + 2); function scroll() { // 在右边显示文本,设置定时器 pos++; //左移文本一步 var scrollerText = ""; //计算要显示的文本 if (pos == length) { pos = -(width + 2); } //如果文本还没有到达左边就要添加一些空格,否则就去掉到达左边的文本 if (pos < 0) { for (var i = 1; i <= Math.abs(pos); i++) { scrollerText = scrollerText + " ";} scrollerText = scrollerText + scrtxt.substring(0, width - i + 1); } else { scrollerText = scrollerText + scrtxt.substring(pos, width + pos); } window.status = scrollerText; //把文本写到状态栏 setTimeout("scroll()", 100); // 100毫秒之后再调用函数 } // --> </SCRIPT> </HEAD> <BODY onLoad="scroll()"> 你的HTML文档放在这里 </BODY> </HTML> 函数scroll()的主体部分用来计算文本的哪一部分要被显示。滚动程序的开始部分是计算和显示,末尾设置定时器,在100毫秒之后执行scroll()函数。为启动文本滚动程序,本程序使用了JavaScript的onLoad事件处理程序(event handler),并放在<BODY>标签中,这意味在HTML页面加载之后立即调用函数scroll()。如果读者要了解本程序的细节,请参考本书提供的JavaScript参考文献。
19.7 预定义对象
JavaScript可以使用一些预先定义的对象,例如,日期对象(Date object)、数组对象(Array object)和数学对象(Math object)等等。
19.7.1 时间对象
顾名思义,日期对象让你处理日期和时间,例如,计算到放假还有多少天,或者把实际的时间加到你的网页等。 为了存取日期和时间,JavaScript定义了Date对象,并且可使用new操作符让程序员创建用户自定义的对象。例如,创建一个名为“today”的对象, today= new Date() 使用日期对象时要注意到:①如果在创建这个对象时不指定确定的日期和时间,执行这条程序时就使用当前的日期和时间,②日期对象提供了一些处理法,例如,getHours(), setHours(), getMinutes(), setMinutes(), getMonth()和setMonth()等等。③日期对象不代表时刻在变化的时钟。 为了设置日期和时间,可使用称为“日期构造程序(Date constructor)”的Date()处理法。例如, today= new Date(2000, 0, 1, 0, 0, 5) 将创建一个today的日期对象,它表示2000年1月1日零点零分5秒(0:0:5)。要注意的是,1月要使用“0”而不是使用“1”来表示,2月使用“1”表示。它的一般形式是: Date(year, month, day, hours, minutes, seconds) [例19.1]下面是一个输出实际日期的程序: <SCRIPT LANGUAGE="JavaScript"> <!-- hide now= new Date(); document.write("Time: " + now.getHours() + ":" + now.getMinutes() + "<br>"); document.write("Date: " + (now.getMonth() + 1) + "/" + now.getDate() + "/" + (now.getYear())); // --> </SCRIPT> [例19.2] 下面是一个显示时钟的程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide var timeStr, dateStr; function clock() { now= new Date(); today= new Date() //时间 hours= now.getHours(); minutes= now.getMinutes(); seconds= now.getSeconds(); timeStr= "" + hours; timeStr+= ((minutes < 10) ? ":0" : ":") + minutes; timeStr+= ((seconds < 10) ? ":0" : ":") + seconds; document.clock.time.value = timeStr; // 日期 date= now.getDate(); month= now.getMonth()+1; month= ((month < 10) ? "0" : "")+ month; year= now.getYear(); dateStr= "" + month; dateStr+= ((date < 10) ? "/0" : "/") + date; dateStr+= "/" + year; document.clock.date.value = dateStr; Timer= setTimeout("clock()",1000); } // --> </SCRIPT> </HEAD> <BODY ONLOAD="clock()"> <FORM name="clock"> 时间:<INPUT TYPE="text" NAME="time" SIZE="8" VALUE=""><BR> 日期:<INPUT TYPE="text" NAME="date" SIZE="8" VALUE=""> </FORM> </BODY> </HTML> 在浏览器上将显示如图19-14所示的页面。
 图19-14 时钟显示
19.7.2 数组对象
数组对象(Array object)或者称为阵列对象是JavaScript的核心对象之一。我们可以设想,如果要存储100个不同的名称,就要定义100个不同的变量并且为它们指定不同的名称,这是相当费事的。如果使用JavaScript的Array对象,就可以使用一个名称(例如,myArray)和一个号码(例如,0,1,…)来存取它们,因为数组是可以被看成由许多变量捆绑在一起的。使用JavaScript的数组构造程序new Array()可以创建一个新的数组,然后就可以给这个数组中的每个变量赋值。例如, <SCRIPT LANGUAGE="JavaScript"> <!-- hide colorArray= new Array(); colorArray[0]= "red"; colorArray[1]= "green"; colorArray[2]= "blue"; colorArray[3]= 255; for (var i= 0; i< 4; i++) { document.write(colorArray[i] + "<br>");} // --> </SCRIPT> 在浏览器上将显示如图19-15所示的页面。
 图19-15 数组对象演示页面
19.7.3 数学对象
如果需要数学计算,可以使用JavaScript提供的数学对象(Math object)。例如,要计算sin(10),可用下面的程序: <SCRIPT LANGUAGE="JavaScript"> <!-- hide var z var x=10 z=Math.sin(x); document.write("z= " + z +"<BR>"); // --> </SCRIPT> 计算结果:z= -0.5440211108893698。 如果程序中要使用几个Math常数和处理法,为避免重复可利用JavaScript的with语句进行计算。例如,要计算πr2,r×cos(π/6)和r×sin(π/6),可编写如下的计算程序: <SCRIPT LANGUAGE="JavaScript"> <!-- hide var a, x, y var r=10 with (Math) { a = PI * r * r x = r * cos(PI) y = r * sin(PI/2) } document.write("a= " + a + "<BR>"); document.write("x= " + x + "<BR>"); document.write("y= " + y); // --> </SCRIPT> 在浏览器上将显示如图19-16所示的页面。
 图19-16 数学对象演示页面
19.8 确认输入
在访问因特网上的站点时,经常会遇到要求用户填写许多表交易单(form),或者称为表单。交易单的输入经常要送到服务器(server),或者通过电子邮件送到某个账号。如果要验证用户输入的信息是否有效可使用JavaScript程序。例如,使用下面的程序可检查你输入的姓名和电子邮件地址是否符合规范。 <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- Hide function test1(form) { if (form.text1.value == "") alert("请输入字符串!") else alert("Hi "+form.text1.value+"! 下一步!"); } function test2(form) { if (form.text2.value == "" || form.text2.value.indexOf('@', 0) == -1) alert("无效的电子邮件地址!"); else alert("下一步!"); } // --> </SCRIPT> </HEAD> <BODY> <FORM name="first"> 输入你的姓名:<BR> <INPUT TYPE="text" NAME="text1"> <INPUT type="button" NAME="button1" VALUE="检验" ONCLICK="test1(this.form)"> <P>输入你的邮件地址:<BR> <INPUT TYPE="text" NAME="text2"> <INPUT type="button" NAME="button2" VALUE="检验" ONCLICK="test2(this.form)"> </FORM> </BODY> </HTML> 在浏览器上将显示如图19-17所示的页面。
 图19-17 检查用户输入信息演示页面
如果想把浏览器上用户输入的交易单交给服务器处理,就需要使用公共网关接口CGI(Common Gateway Interface)程序。CGI是服务器(例如,HTTP服务器)和资源(例如,数据库)之间的通信规范。
19.9 JavaScript动画
19.9.1 图像对象
JavaScript定义了图像对象(Image object),通过图像对象的属性和处理法可以改变Web网页上的图像,因此也可以让用户创建JavaScript型的动画。 JavaScript动画是通过重复设置图像的src属性来实现的。这种动画比GIF动画慢,即每秒钟显示的图像的帧数比较少。GIF (Graphics Interchange Format,图形文件交换格式)是Web页面上使用最普遍的图形文件格式之一,使用这种格式制成的动画存放在一个文件中,而JavaScript动画的每一帧图像是单独的一个文件,即一个对象,而且每个文件都要通过网络加载,即要和主机连接然后传输图像数据,这就很费时间,因此就显得比较慢。尽管如此,在网络上还是得到广泛的应用。 在JavaScript中,所有图像可以通过图像数组(Array)来表示,这个数组称为images(图像),这是document(文档对象)的属性。网页上的每一幅图像都分配一个号码,第一幅图像为“0”号,第二幅图像为“1”号,…。因此,document.images[0] 就表示第一幅图像,依此类推。在HTML文档中,每一幅图像都被认为是一个图像对象(Image object)。一个图像对象有一些许多属性可通过JavaScript来存取,例如,图像的高度和宽度,对齐方式等等。而document.images[0].width就表示Web网页上的第一幅图像的宽度,宽度的数值用象素作单位。 如果在一个Web网页上有许多图像,可以给每幅图像起一个不同的名称,这就比人去记忆每一幅图像的编号要容易些。如果用下面的标签声明一幅图像, <IMG SRC="img.gif" name="myImage" WIDTH=100 HEIGHT=100> 你就可以通过document.myImage或者document.images["myImage"]来寻找这幅图像。
19.9.2 加载和更新图像
如果我们要在网页的同一个位置上改变显示的图像,就需要使用Image(图像)对象的SRC属性。我们已经知道,在HTML的<IMG>标签中,SRC代表的是图像的URL地址,因此在使用JavaScript时就可以把新的图像地址赋予给已经加载显示过的图像地址,这样新的图像就可以代替旧的图像。例如, <BODY> <IMG SRC="image1.gif" name="myImage" WIDTH=100 HEIGHT=100> <INPUT type=button VALUE="改变图像" ONCLICK="document.myImage.src='image2.gif'"> </BODY> 第一条程序是加载image1.gif(图像1),它的名称定义为myImage(我的图像);第二条程序是用新的图像image2.gif(图像2)代替老的图像image1.gif(图像1)。
19.9.3 预加载图像
由于在因特网上传输图像很费时间,在演示动画时很可能会导致动画不连续,令人难以接收,因此可考虑使用预先下载图像的方案。为此需要创建一个图像数组和新的图像对象,如下所示(本例的动画由4幅图组成): hiddenImg = new Array() //构造一个图像数组 for(i = 0; i < 4; i++) { //预加载图像 hiddenImg[i] = new Image() //构造新的图像对象 hiddenImg[i].src = "image" + i + ".gif" //图像的URL地址 } 其中,hiddenImg [i]= new Image()的含义是使用图像构造程序new Image()来创建一个名为“hiddenImg”的新图像对象;hiddenImg[i].src = "image" + i + ".gif"的含义是通过hiddenImg对象来表示图像的地址。我们已经知道,给SRC属性赋予一个新地址,就意味着迫使Web浏览器加载这个地址所指示的图像。因此,当执行这行程序时,就加载第 i 幅图像imagei.gif。正如对象名hiddenImg(隐藏图像)的含义,在Web浏览器完成加载之后,这些图像是不显示的,仅仅是存放在内存中为以后使用。为了显示这幅图像,例如显示第i幅图像,可使用下面的语句: document.myImage.src= hiddenImg[i].src 下面是点击一次按钮显示一幅图像的完整程序: <HTML> <HEAD><TITLE>预加载图像</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- hide hiddenImg = new Array() for(i = 0; i < 4; i++) { hiddenImg[i] = new Image() hiddenImg[i].src = "image" + i + ".gif" } ImgNum=0 function animation (){ document.myImage.src= hiddenImg[ImgNum].src; ImgNum++; if(ImgNum > 3) { ImgNum = 0 } } // --> </SCRIPT> </HEAD> <BODY> <IMG SRC="image1.gif" name="myImage" WIDTH=123 HEIGHT=112> <FORM> <INPUT type="button" VALUE="显示一幅图像" ONCLICK="animation ()"> </FORM> </BODY> </HTML>
19.9.4 JavaScript动画程序举例
以上介绍了JavaScript动画的基本原理,下面给出一个显示动画的程序供参考。 <HTML> <HEAD><TITLE>JavaScript的动画入门 </TITLE></HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide delay = 1000 imageNum = 0 //预先加载动画图像;该动画由4幅图像组成。 theImages = new Array() for(i = 0; i < 4; i++) { theImages[i] = new Image() theImages[i].src = "image" + i + ".gif" } //动画函数 function animate() { document.animation.src = theImages[imageNum].src imageNum++ if(imageNum > 3) { imageNum = 0 } } //减低帧速率函数 function slower() { delay+=100 if(delay > 4000) delay = 4000 } //提高帧速率函数 function faster() { delay-=100 if(delay < 0) delay = 0 } // --> </SCRIPT> <BODY BGCOLOR="white"> <IMG SRC="image0.gif" name="animation" HEIGHT="112" WIDTH="123" ALT="[Animation]" ONLOAD="setTimeout('animate()', delay)" BORDER="2" HSPACE="15"> <FORM> <INPUT TYPE="button" VALUE="减低帧速" ONCLICK="slower()"> <INPUT TYPE="button" VALUE="提高帧速" ONCLICK="faster()"> </FORM> </BODY> </HTML> 在浏览器上将显示如图19-18所示的页面。
… …  图19-18 JavaScript的动画演示页面
19.10 层对象
19.10.1 层对象的概念
HTML网页上的层(layer)就像一叠纸中的一张纸。其中,一张纸上写有文本,在另一张纸上画有图画,在第三张纸上的图画周围写有一些文字,等等,每一张纸就就是一层。从这个观点来看,层就像一个容器,它可以容纳像文本、交易单和图像这类对象。如果移动某一张纸,这张纸上的所有对象也就跟着移动。把这些“纸”放到HTML页面上,借助JavaScript的帮助,可以给这些对象(如图像)进行定位,可以在HTML页面上移动它们,也可以隐藏对象。每一张纸可以有透明的部分,犹如在纸上挖一个洞,下一层的对象就可显示出来。 目前,只有Netscape公司的Communicator浏览器支持层对象。
19.10.2 创建层对象
创建层对象需要使用<LAYER>或者<ILAYER>标签。<LAYER>用于HTML的内容定位,称为层标签。被定位的内容可以相互叠加,可以是透明的或者是不透明的,可以是可见的也可以是不可见的。层标签也可以嵌套使用。<LAYER>用来指定内容绝对位置,<ILAYER>用来指定内容的相对位置。如果没有指定位置,层将显示在浏览器窗口的左上角。层的一些可用属性如表19-02所示。
表19-02 层对象的属性
属性 |
说明 |
name="layerName" |
层的名称 |
left=xPosition |
距离左上角的水平位置 |
top=yPosition |
距离左上角的垂直位置 |
z-index=layerIndex |
层索引号 |
width=layerWidth |
层的宽度(以象素为单位) |
clip="x1_offset, y1_offset, x2_offset, y2_offset" |
定义层的显示宽度 |
above="layerName" |
定义新创建的层要在哪一层上面 |
below="layerName" |
定义新创建的层要在哪一层下面 |
Visibility=show|hide|inherit |
层的可视性 |
bgcolor="rgbColor" |
背景颜色 |
background="imageURL" |
背景图像 |
例如,要创建两个层对象,第一层放图像,第二层上放文本,而且文本要显示在图像上,可以使用下面的程序实现: <HTML> <LAYER ID=pic Z-INDEX=0 LEFT=50 TOP=10> <IMG SRC="red.gif" WIDTH=108 HEIGHT=103> </LAYER> <LAYER ID=txt01 Z-INDEX=1 LEFT=50 TOP=10> <FONT SIZE=+2> <I> <FONT COLOR="#00FFFF">这是文字层</FONT> </I> </FONT> </LAYER> </HTML> 在这个程序中使用了层的索引属性Z-INDEX,它也表示层的出现次序。最高索引号的层将显示在最顶层。 运行这个程序后在浏览器上将显示如图19-19所示的页面。
 图19-19 层对象演示页面
19.10.3 层与JavaScript
通过JavaScript可以访问层。访问某层的首要条件是要知道层在JavaScript中的表示方法。其中一种比较好的方法是给每一层起一个名字。如果用下面的方法来命名层, <LAYER ... NAME=myLayer> …… </LAYER> 我们就可以通过document.layers["myLayer"]来访问这层。按照Netscape公司提供的文档,也可以写成document.myLayer。 此外,我们也可以通过整数索引号来访问层。为了访问最低层,可以使用document.layers[0]。但要注意,整数索引号与z-index不等同。例如,layer1的Z-INDEX=15,layer2的Z-INDEX=50,要访问layer1和layer2就要通过document.layers[0]和document.layers[1]来访问,而不是通过document.layers[17]和document.layers[100]来访问。 层有好几个属性,可以使用JavaScript来改变这些属性。下面是一个显示和隐藏层的例子,点击该程序生成的按钮 就可显示和隐藏“这是HTML文档中的一层”文本层。它的源程序如下: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide function showHide() { if (document.layers["myLayer"].visibility == "show") document.layers["myLayer"].visibility= "hide" else document.layers["myLayer"].visibility= "show"; } // --> </SCRIPT> </HEAD> <BODY> <ILAYER ID=myLayer VISIBILITY=show> <FONT SIZE=+1 COLOR="#0000ff"><I>这是HTML文档中的一层</I></FONT> </ILAYER> <FORM> <INPUT type="button" VALUE="显示/隐藏层" ONCLICK="showHide()"> </FORM> </BODY> </HTML>
19.10.4 层对象的移动
利用层的left(左)和top(顶)属性,可以给层对象赋予新的数值,从而产生移动的效果。下面就是产生这种效果的一个程序: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide var pos=0 var direction function move() { if (pos < 0) direction= true; if (pos > 200) direction= false; if (direction) pos++ else pos--; document.layers["myLayer2"].left= pos; } // --> </SCRIPT> </HEAD> <BODY ONLOAD="setInterval('move()', 20)"> <ILAYER ID=myLayer2 LEFT=0> <FONT SIZE=+1 COLOR="#0000ff"><I>这是HTML文档中的一层</I></FONT></ILAYER> </BODY> </HTML> 该程序加载之后,“这是HTML文档中的一层”就会在浏览器窗口上周而复始地左右移动。 在这个程序中,使用<ILAYER> … </ILAYER>标签创建了一个称为myLayer2的层;为了在网页加载之后立即产生“这是HTML文档中的一层”的移动效果,在<body>标签中使用了ONLOAD事件处理程序中的处理法setInterval( ),这是JavaScript 1.2的新处理法,使用它可以定时调用函数。ONLOAD="setInterval('move()', 20)"表示每隔20毫秒调用一次move()函数,用它来设置层的位置。 此外,层不仅可以叠加。而且在叠层上的对象也可以移动。下面所示的程序就可以使“这是HTML文档中的一层”对象在图对象的上面左右移动: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide var pos=0 var direction function move() { if (pos < 0) direction= true; if (pos > 200) direction= false; if (direction) pos++ else pos--; document.layers["myLayer"].left= pos; } // --> </SCRIPT> </HEAD> <BODY ONLOAD="setInterval('move()', 20)"> <ILAYER ID=pic Z-INDEX=0 LEFT=60 TOP=10 HEIGHT=108 WIDTH=103> <IMG SRC="red.gif" WIDTH=108 HEIGHT=103 > </ILAYER> <ILAYER ID=myLayer Z-INDEX=1 LEFT=0 TOP=-60 > <FONT SIZE=+2 COLOR="#0000ff"><I>这是HTML文档中的一层</I></FONT></ILAYER> <LAYER ID=txt Z-INDEX=2 LEFT=50 TOP=120> <FONT SIZE=+1> 文字显示在图像层上左右移动</FONT> </LAYER> </BODY> </HTML> 在Netscape公司的Communicator浏览器上将显示如图19-20所示的左右移动的页面。

图19-20 层对象的移动演示页面
19.10.5 图像的剪取
使用HTML的属性可以定义层上哪一矩形部分可以被显示出来,这个功能称为图像对象剪取(clipping)。例如,使用下面的程序可以仅仅显示图像的一部分,而其余部分不显示。 <ILAYER LEFT=0 TOP=0 CLIP="20,25,110,120"> <IMG SRC="art01.jpg" WIDTH=404 HEIGHT=212> </ILAYER> 在这个程序中,整幅图像的尺寸是404×212象素,显示部分为90×95象素。在HTML的标签<ILAYER> … <ILAYER>之间,CLIP属性的前两个参数定义左上角的坐标,后两个参数定义右下角的坐标,如图19-21所示。
 图19-21 图像对象的剪取
通过改变对象层的clip.left, clip.top, clip.right和clip.bottom属性,也就是赋予新的象素值,剪取图像将发生变化。下面的程序将动态地演示剪取的图像: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide var middleX, middleY, pos; function start() { // 获取图像尺寸 var width= document.layers["imgLayer"].document.art01.width; var height= document.layers["imgLayer"].document.art01.height; //计算图像的中点坐标 middleX= Math.round(width/2); middleY= Math.round(height/2); //开始位置 pos= 0; //开始显示! show(); } function show() { // 增加图像显示区 pos+= 2; // 每次增加的大小 document.layers["imgLayer"].clip.left= middleX- pos; document.layers["imgLayer"].clip.top= middleY- pos; document.layers["imgLayer"].clip.right= middleX+ pos; document.layers["imgLayer"].clip.bottom= middleY+ pos; //检查整个图像是否显示完毕 if (!((pos > middleX) && (pos > middleY))) setTimeout("show()", 20); } // --> </SCRIPT> </HEAD> <BODY> <ILAYER ID="imgLayer" CLIP="0,0,0,0"> <IMG name="art01" SRC="art01.jpg" WIDTH=404 HEIGHT=212> </ILAYER> <FORM> 按此按钮开始显示图像:<INPUT type=button VALUE="开始" ONCLICK="start()"> </FORM> </BODY> </HTML> <BODY>部分的按钮用来调用函数start()。该函数在计算开始显示点之后就调用函数show()。函数show()的最后设置定时器,在整幅图像没有显示完之前,每隔20毫秒调用一次函数show(),直到整幅图显示完毕。请注意,在函数start()中获取图像尺寸的程序: var width= document.layers["imgLayer"].document.art01.width; var height= document.layers["imgLayer"].document.art01.height; 通过document.layers["imgLayer"]可以访问称为imgLayer的层对象,但为什么在document.layers["imgLayer"]之后还要使用document(文档)?这是因为每一层都含有它自己的HTML页面,这也就是意味每一层都有一个document(文档)对象,为了访问imgLayer层中的图像对象就需要访问这个document(文档)对象。在本例中的图像对象是art01。 为便于调试程序,设置了一个开始按钮。在Communicator浏览器上点击 按钮,执行该程序的结果如图19-22所示。
 图19-22 JavaScript图像剪取的演示页面
19.10.6 嵌套层
我们已经知道一层可以包含几个不同的对象。一层也可以包含其他的层,这就叫做层的嵌套。它的用途可以通过下面的两个例子来体会。 [例19.3] 一个称为父层(parentLayer)的包含两个子层1(layer1)和层2(layer2),在<BODY>部分还有3个按钮,这些按钮用来启动/停止层的移动。在Communicator浏览器中可以看到,parentLayer的移动会带动其他两个层一起移动,而layer1或者layer2的移动则不会影响其他层的移动。它的源程序如下所示: <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide // 开始位置 var pos0= 0; var pos1= -10; var pos2= -10; // 要移动? var move0= true; var move1= false; var move2= false; //方向? var dir0= false; var dir1= false; var dir2= true; function startStop(which) { if (which == 0) move0= !move0; if (which == 1) move1= !move1; if (which == 2) move2= !move2; } function move() { if (move0) { // 移动parentLayer if (dir0) pos0-- else pos0++; if (pos0 < -100) dir0= false; if (pos0 > 100) dir0= true; document.layers["parentLayer"].left= 100 + pos0; } if (move1) { //移动parentLayer if (dir1) pos1-- else pos1++; if (pos1 < -20) dir1= false; if (pos1 > 20) dir1= true; document.layers["parentLayer"].layers["layer1"].top= 10 + pos1; } if (move2) { //移动parentLayer if (dir2) pos2-- else pos2++; if (pos2 < -20) dir2= false; if (pos2 > 20) dir2= true; document.layers["parentLayer"].layers["layer2"].top= 10 + pos2; } }// --> </SCRIPT> </HEAD> <BODY ONLOAD="setInterval('move()', 20)"> <ILAYER ID=parentLayer LEFT=100 TOP=10> <LAYER ID=layer1 Z-INDEX=0 LEFT=0 TOP=-10> 这是第一层(first layer) </LAYER> <LAYER ID=layer2 Z-INDEX=1 LEFT=200 TOP=-10> 这是第二层(second layer) </LAYER> <BR><BR> 这是父层(parent layer) </ILAYER> <FORM> <INPUT type="button" VALUE="移动/停止父层" ONCLICK="startStop(0);"> <INPUT type="button" VALUE="移动/停止第一层" ONCLICK="startStop(1);"> <INPUT type="button" VALUE="移动/停止第二层" ONCLICK="startStop(2);"> </FORM> </BODY> </HTML> 在这个程序中可以看到,在parentLayer内部定义了两个层,这就是嵌套层。这些层的访问是通过JavaScript的函数function move()实现的: document.layers["parentLayer"].left= 100 + pos0; … document.layers["parentLayer"].layers["layer1"].top= 10 + pos1; … document.layers["parentLayer"].layers["layer2"].top= 10 + pos2; 要注意的是,访问layer1和layer2嵌套层不能仅仅用document.layers["layer1"]或者用document.layers["layer2"],因为它们是在parentLayer内。在Communicator浏览器上将显示如图19-23所示的移动文本。
 图19-23 JavaScript文本嵌套层的演示页面
[例19.4] 图像对象在指定的剪取区中上下移动。 <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- hide var pos= 0; //开始位置 var direction= false; function moveNclip() { if (pos<-180) direction= true; if (pos>40) direction= false; if (direction) pos+= 2 else pos-= 2; document.layers["clippingLayer"].layers["imgLayer"].top= 100 + pos; } // --> </SCRIPT> </HEAD> <BODY ONLOAD="setInterval('moveNclip()', 20);"> <ILAYER ID="clippingLayer" Z-INDEX=0 CLIP="25,25 320,125" TOP=0 LEFT=0> <ILAYER ID="imgLayer" TOP=0 LEFT=0> <IMG ID=art01 SRC="art01.jpg" WIDTH=404 HEIGHT=212> </ILAYER> </ILAYER> </BODY> </HTML> 在Communicator浏览器上将显示如图19-24所示的上下滚动页面。
 图19-24 JavaScript图像嵌套层的演示页面
19.11 层叠样式和JavaScript样式
在为HTML文档引入样式(style)之前,Web网页的作者对网页文档格式的控制很有限。例如,不能设置网页的边界,指定行的高度或者文本的边框和位置等等。样式信息可以在HTML文档中指定,也可以使用外部的样式单(style sheet)文件。样式信息可用于单个文素,也可以用于一组文素。使用样式可以让作者指定Web网页格式的许多属性,这样可以使整个网页更加美观,它的风格也容易取得一致。 万维网协会W3C(World Wide Web Consortium)于1996年12月提出了称为层叠样式单版本1(Cascading Style Sheets, level 1,CSS1)推荐标准。该标准在HTML中使用<STYLE>和</STYLE>标签来指定样式。 [例19.5] 使用CSS1样式定义标题1(H1)的颜色为红色,源程序如下: <HTML> <HEAD> <TITLE>层叠样式单版本</TITLE> <STYLE TYPE="text/css"> H1 { color: red} </STYLE> </HEAD> <BODY> <H1>大字标题是红色</H1> <P STYLE="color: blue">而这个段落的文字是蓝色的 </BODY> </HTML> 在<STYLE TYPE="text/css">中定义了样式的类型,表示文字用css样式。使用JavaScript编写样式时,要用<STYLE TYPE="text/JavaScript">。 [例19.6] 使用JavaScript定义段落中的文字字号为14磅,距离左边距为200磅,字的颜色为红色,标题3(H3)的字体颜色为蓝色。源程序如下: <HTML> <HEAD> <TITLE> type_Document_Title_here </TITLE> <STYLE TYPE = "text/javascript"> tags.P.fontSize = "14pt"; tags.P.marginLeft = "200pt"; tags.P.color = "red"; tags.H3.color = "blue"; </STYLE> </HEAD> <BODY> <H3 ALIGN="CENTER">网页制作</H3> <p>编写HTML文档是每个大学生都要具备的基本技能 </BODY> </HTML> [例19.7] 下面的源程序用来创建一个样式类(style class)并把它应用到使用<LAYER>创建的层[1]。 <HTML> <HEAD> <TITLE>层叠样式单</TITLE> <STYLE TYPE="text/css"> <!-- all.styleN { color:magenta; border-width:20px; border-color:cyan; border-style:ridge; padding:5%; }--> </STYLE> </HEAD> <BODY BGCOLOR=white> <LAYER ID=layerN TOP=10 LEFT=20 BGCOLOR="#FFFFCC" CLASS=styleN> <H1 ALIGN="CENTER">Layer N </H1> <P>请使用这是一个色彩丰富的层</P> </LAYER> </BODY> </HTML> 在Communicator浏览器上的输出如图19-25所示。
 图19-25 层叠样式演示页面
在这个例子中用到了CLASS=styleN,其中的CLASS称为“类”。这是HTML新添加的一个属性,表示在<BODY>和</BODY>之间所有的文档元素都可以被分成类,在样式单中这些类可以被寻址。下面的例子进一步说明了类的概念 <HTML> <HEAD> <TITLE>Title</TITLE> <STYLE TYPE="text/css"> H2.Students { color: blue } </STYLE> </HEAD> <BODY> <H2 CLASS=Students>大学生的素质</H2> 近来对大学生的素质进行了调查… <H2 CLASS=Students>调查结果分析</H2> … </BODY> </HTML> 在这个程序中,“大学生的素质”和“调查结果分析”是属于同一类。在Communicator浏览器上的输出如图19-26所示。
 图19-26 类概念的演示页面
练习与思考题
使用HTML编辑器重新输入本章所示的所有源程序,或者根据读者自己的水平有选择地输入比较难理解的源程序,自己设计程序中没有提供的HTML文档、图和AVI等文件,然后使用Web浏览器检查程序的准确性。 参考文献和站点
- http://developer./docs/manuals/communicator/jsguide4/index.htm (浏览日期:1998年11月)
- http://developer./docs/manuals/communicator/jsref/index.htm (浏览日期:1998年11月)
- http://www./javatour/framehol.htm (浏览日期:1999年2月6日)
|