第一章
JavaScript 是什麽?
JavaScript 是一种新的描述语言,此一语言可以被箝入 HTML 的文件之中。透过 JavaScript 可以做到回应使用者的需求事件(如:form的输入)而不用任何的网路来回传输资料,所以当一位使用者输入一项资料时,它不用经过传给伺服端(server)处理,再传回来的过程,而直接可以被客户端(client)的应用程式所处理。你也可以想像成有一个可执行程式在你的客端上执行一样!目前已有一些写好的程式在Internet上你可以连过去看看,以下有一些计算器的例子,在Nescape上。JavaScript和Java很类似,但到底并不一样!Java是一种比JavaScript更复杂许多的程式语言,而JavaScript则是相当容易了解的语言。JavaScript创作者可以不那麽注重程式技巧,所以许多Java的特性在JavaScript中并不支援。如需相关的更多资讯,可以去读读Netscape的有关NetscapeJavaScript之介绍。
如何执行JaveScript?
JavaScript如何执行呢?
Netscape2.0beta3版以上,就可以执行JavaScript的功能了,我们测试过至少beta3版以上可以,其他种类的WWW浏览器如:InternetExpore3.0也有此一功能。
范例1:
以下我们就以一些例子来告诉你如何将JavaScript写在HTML文件中,并且体会一下新语言的特性,我们从第一个例子开始:如何用JavaScript印出一串文字至HTML文件中:
<html>
<head>
MyfirstJavaScript!
</head>
<body>
<br>
ThisisanormalHTMLdocument.
<br>
<scriptlanguage="LiveScript">
document.write("这是以JavaScript印出的!")
</script>
<br>
BackinHTMLagain.
</body>
</html>
如果你使用的WWW浏览器是Netscape2.0beta3以上版本的话,那你就可以看到相关的结果,而如果你的浏览器并非是可以支援JavaScript的话,那看起来就会有一些怪怪的了,以上范例的结果如下:
ThisisanormalHTMLdocument.
这是以JavaScript印出的!
BackinHTMLagain.
此一范例并没有太大的用处,它只是要告诉你如何使用<script>的标签,并如何将它置於HTML的文件之中而已,这个新的标签你可以特它放在文件中的任何地方。
范例2:
接下来下一个例子所要介绍的是有关函数(function)的使用。请放心,函数并非很难懂的东西,但它却相当有用。函数通常是在HTML文件中<body>的部份被呼叫,而理所当然地,它最好事先被宣告并放在HTML文件中<body>的部份。好让在<body>部分中使用到函数时,它已确定被读取住来。另外,<script>标签的有关描述语法剖份,你可以用注解的符号将它括起来,以免旧版或无法读取JavaScript的浏览器读到,而误会了意思!
<html>
<head>
<scriptlanguage="LiveScript">
functionpushbutton(){
alert("嗨!你好");
}
</script>
</head>
<body>
<form>
<inputtype="button"name="Button1"value="Pushme"onclick="pushbutton()">
</form>
</body>
</html>
如果你是使用Netscape2.0beta3以上的浏览器,那以上JavaScript语法部份的结果如下,你可以试着按按钮看看有何结果产生!在范例2中,将会产生一个按钮,当你用滑鼠去按它的时候,应该会出现一个视窗上面有“嗨!你好”的字串,如何?不错吧!这个结果是如何产生的呢?首先,在<head>内的函数会被载入并存於内存中,接着一个新的<form>标签<inputtype="button".....>将产生一个接钮。然後,你可以在後面看到'onClick'的指令,这就是告诉浏览器,当该按钮被按时,应会执行onClick後的函数'pushbutton()',而这个函数在刚刚程式被载入时就已安放在记忆体中了!请注意,在这个函数中我们用到了个新东西-alert的method,是JavaScript事先定义好的,它会以对话视窗产生内涵的讯息,并有一"确定"(OK)的按钮。JavaScript定义了许多的method,你可以连至Netscape公司去获取较完整的讯息。我想这些method在不久的将来会有长长的一串可以够你学的,不过目前的method也已经可以做出相当多东西了!接着下个例子将告诉你如何由一个输入型表格中读入使用者的输入资料,事实上,这也是加入个函数就可以达成的。
范例3:
<html>
<head>
<scriptlanguage="LiveScript">
<!--hidescriptfromoldbrowsers
functiongetname(str){
alert("哈罗!"+str+"!");
}
//endhidingcontents-->
</script>
</head>
<body>
Pleaseenteryourname:
<form>
<inputtype="text"name="name"onBlur="getname(this.value)"value="">
</form>
</body>
</html>
现在你可以试试结果如何:
请输入你的名字:
在这个例子中又有新的东西了。首先,让我们注意一下,在语法中的注解部分(<!-...->)此部分即我们之前所提到的它可以避免旧版本或是不支援JavaScript的WWW浏览器因为不认识这些函数而产生错误。它的顺序应该为<script>先,接着为注解的开头<!-,然後是内容,注解尾->,最後是</script>。另外要注意的一点是,语解尾那一行的开头双斜线"//",不可以省略,它代表了JavaScript的注解,若省略了的话,->之前的字会被误认为是JavaScript的指令。这个例子可以让使用者输入一段文字,然後再输入完毕後经由<input>标签中的"onBlur"事件函数侦知,於是呼叫Getname(Str)这个函数来加以取得输入字串,并将它显示在对话视窗上!函数Getname(this.value)中的"this.value"是你在文字输入格式中所输入的值。
范例4::
这个范例更是帅了!我们在HTML文件档完成了以後,常会加上一行文件最後修改的日期,现在你可不用担心每次都要去改或是忘了改了。你可以很简单的写一个如下的描述语法程式,就可以自动的为你每次产生最後修改的日期了:
<html>
<body>
ThisisasimpleHTML-page.
<br>
Lastchanges:
<scriptlanguage="LiveScript">
<!--hidescriptfromoldbrowsers
document.write(document.lastModified)
//endhidingcontents-->
</script>
</body>
</html>
以上的document.lastModified叁数在Netscape2.0beta2版时是被写成documeut.lastmodified的,然而,之後的版本就改为document.lastModified,所以注意一下;JavaScript本身是会区分大小写的,lastmodified与lastModified在它看来是不同的结果。最後,在这一部分结束之前,要提醒你一点,像范例4,的用法并非每一部机器都是一样的,例如:PC上跑得很正确的,在工作站上不一定会有相同的结果,所以,或许你仍得测一测不同机器的结果才会有所定论。当然,这一切是因为JavaScript还正在发展的原因,最新的讯息还是得去拜访一下Netscape公司才知道。也许你也不用奇怪,当你隔周再来访时,JavaScript可能又作了相当大的改变了呢!
第二章
范例5:
在这一部分首先要为你展示的JavaScript特性是将你的滑鼠移到这个不同颜色的连结上面,此时看看浏览器下的状态列有何结果。然後这样的功能我们可以与JavaScript的功能相结合。好,现在再将你的滑鼠移到本处不同颜色的连结上面,你应该会发现有一个视窗出现,是吧?!如何!怎麽做到的呢?以下就是这一个连结的作法:<ahref="tpage.htm"onMouseOver="window.status='Justanotherstupidlink...';returntrue">在这儿你只要在传统<a>的标签中加入onMouseOver的method,就可达成你要的效果了。这里的window.status是用来让你可以在WWW浏览器的状态列上显示一些讯息用的。在语法中,你可以看到讯息部分是用'括起来的部分,而非以"括起来,在讯息部分结束之後,必须加上;returntrue。好了,利用以上的特性可以很简单的完成第二个连结的例子!相当简单,以onMouseOver的method然後配合事件发生时去呼叫函数hello()就行了,不再多加解释了,作法如下:
<html>
<head>
<scriptlanguage="LiveScript">
<!--Hiding
functionhello(){
alert("哈罗!");
}
</script>
</head>
<body>
<ahref=""onMouseOver="hello()">link</a>
</body>
</html>
范例6:
接下来我们要告诉你一个使用日期和时间的例子。在第一部分中,你已看过了lastModified的用法和作法。现在要告诉你的并非是印出网路上伺服器或文件修改日期,而是你个人客户端机器的日期和时间。以下就是执行结果:
现在时间是:15:49
今天日期为:5/26/2005
做法如下:
<scriptlanguage="LiveScript">
<!--Hiding
today=newDate()
document.write("现在时间是:",today.getHours(),":",today.getMinutes())
document.write("<br>今天日期为:",today.getMonth()+1,"/",today.getDate(),"/",today.getYear());
//endhidingcontents-->
</script>
在本例中,我们必需首先建立一个日期变数,这可以由today=newDate()来完成。如果没有特别指定时间与日期的话,浏览器将会采用本地客户端机器的时间,若将它放入变数today中。这儿要注意的是:我们并没有宣告today这个变数的型态,这和Java或其他的程式语言在用到变数之前必需先加以宣告的方式有相当大的不同。在完成today的日期变数後,我们等於建立了一个具有本地时间与日期的物件(object)。接着就可以使用get...的method以取得today这个物件的时间和日期。请注意getMonth这个method所取得的月份范围是由0~11,所以必须加1以代表真正的1月至12月。看完以上的例子後,想想你可以使你的文件变得有点智慧,例如:某个文件有时效限制的话,你可以利用我们在上一部份的范例4中所提到的功能和这一个范例中所学习到的功能,设计一个让你的文件在第10天以後读到的话就会告诉读者:"喂!这篇已过时了!"的程式,试试看,并不难!除以上功能外,在建立日期物件时你也可以事先设定日期如下:docStarted=newDate(96,0,13)首先是年(西元),接着是月(但记得减1),再接着是日。同样的方法也可以加上时间的设定,如下:
docStarted=newDate(96,0,13,10,50,0)
前三个是日期的年、月、日,接着是时、分、秒。最後,我们必须提醒你,JavaScript并没有实际的日期型态,但是它却能毫不费力地显示出日期和时间,原因是它是从1/1/19700:0h开始以ms(milliseconds)来计算目前的时间的,这听起来似有些复杂,但你倒不用担心,它有标准的共用函数可以计算,你只要知道如何用就可以了!
范例7:
接下来我们要为你介绍一个可以产生乱数的函数,也是以JavaScript所写的。这个函数只是利用了一点小技巧而已,而这种技巧在大部分的编译器(compiler)中,大都是如此(或类似)计算出乱数来的。我相信JavaScript最後应也会以相似的方法来产生这样的method,如果它会提供这样功能的话。以下是此函数的结果:这是一个计算产生的乱数:0.6840756821474804
以下是这个作法的写法:
<html>
<head>
<scriptlanguage="LiveScript">
functionRandomNumber(){
today=newDate();
num=Math.abs(Math.sin(today.getTime()));
returnnum;
}
</script>
</head>
<body>
<scriptlanguage="LiveScript">
<!--
document.write("Thisisarandomnumber:",RandomNumber());
//-->
</script>
</body>
</html>
我们的做法是以上一个范例中的时间函数;它会出现一个很大的数,利用这个数再加以运算即可!例如:将它拿来做正弦函数(sin)的运算,得到的数再做绝对值的运算,结果可以得到一个介於0与1间的实数。因为时间的改变是ms为单位,而且你绝不会获得相同的数字。不过这个做法并不适合拿来快速的连续产生一系列的乱数,但如果你是不定时,久久的用一次,那效果就不错了!
范例8:
JavaScript的一个重要特点是它可以制作视窗。你可以产生一个的视窗,并且在此视窗中载入HTML文件,完全以JavaScript来航游网际网路(Internet)。接下来的范例就是告诉你如何开启一个视窗并且写点东西进去,你可先试试按一下范中之接钮看看!
原始程式如下:
<html>
<head>
<scriptlanguage="LiveScript">
functionWinOpen(){
msg=open("","DisplayWindow","toolbar=no,directories=no,menubar=no");
msg.document.write("<HEAD><TITLE>哈罗!</TITLE></HEAD>");
msg.document.write("<CENTER><H1>酷毙了!</H1><h2>这是<B>JavaScript</B>所开的视窗!</h2></CENTER>");
}
</script>
</head>
<body>
<form>
<inputtype="button"name="Button1"value="Pushme"onclick="WinOpen()">
</form>
</body>
</html>
这儿你又看到用按钮来启动函数。这次的函数WinOpen()是藉着一个open的method来产生一个新的视窗。第一对双引号("")是用来描述欲载入至视窗中的文件URL位置。如果留者空白的话,那就会呈现一个空白视窗,并可以透过JavaScript写入东西!下一对双引号内的内容是这个新开启视窗的名字,你可以喜欢给它任意一个名字,但不可加入空白,如用DisplayWindow的话便会出现错误讯息,请注意。接下来的一连串双引号内所指定的是该视窗的相关性质(properties),这些蛮有趣的,你可以指定要不要有工具棒(toolbar)、卷轴(scrollbar),等等,例如:如果你写toolbar=yes,那就会在你所产生出来的视窗中出现一排工具列。以下有许多你可以改变的视窗特性,请注意它们字中间不可以有空白:
toolbar
location
directories
status
menubar
scrollbars
resizable
copyhistory
width=pixels
height=pixels
以上的pixels部分,你可以填入点数的数值,这数值是告诉浏览器这个视窗的大小。在开启视窗,并且将它称为msg以後,就可以开始写些东西到视窗中了。你可以写入一般正规的HTML语法文字。哇!这可不得了了,也就是说,你可以利用先前使用者在form表格中输入给你的文章直接将它回应至浏览器上来了!这些功能在几个月前大概还只能用CGI才能达到喔!现在你不用CGI也可以做了!
第三章
曾有许多网友问我有关JavaScript与框架(为求方便,以下均用frame表示)合用的问题。事实上,若您同时想用frames和JavaScript的功能,首先您必需拥有NetscapeNavigator2.0(或以上)浏览器(至少目前是如此)。当然也有某些浏览器支援frames的功能--如:Oracle开发的PowerBrowser,但此浏览器还只是Beta版,目前尚不支援JavaScript。首先,我稍微解释一下frames的功用。因为frames功能才开发不久,仍有许多HTML文件中未使用这项新功能。Frames最主要功用是"分割"您的视窗,使每个"小视窗"(frame)能显示不同的HTML文件(译按:这有点类似电视的子母画面)。更妙的是,不同frame之间可以互动(interact),也就是说不同frame之间可以交换讯息与资料(information)。例如:假设您开了两个frames,第一个frame可显示普通HTML文件,第二个frame可显示工具列(toolbar)。此工具列中可包含浏览您homepage所需的各种按钮。如此一来,即使第一个frame载入了另一个HTML文件,您仍可在第二个frame中看到工具列。现在我先将上述特性展示给您瞧瞧。请按一下下面的按钮,看一看frames的长相。(如果您是线上观看此文件,您可能需稍候一下才看得到结果,因为scripts必需由server中载入到您的机器)。
以下是此frame的写法:
<HTML>
<HEAD>
<title>Frames</title>
</HEAD>
<FRAMESETROWS="50%,50%">
<FRAMESRC="frtest1.html"name="fr1">
<FRAMESRC="frtest2.html"name="fr2">
</FRAMESET>
</HTML>
首先您必须告诉浏览器您要开几个frame?这是由<frameset...>这个标签(tag)来宣告。rows这项叁数是告诉浏览器您想将视窗分割成几列?而cols这项叁数是告诉浏览器您想将视窗分割成几行?您也可以用很多组的<frameset...>tags将视窗分割得更复杂。以下是Netsacpe所提到的一个范例:
<FRAMESETCOLS="50%,50%">
<FRAMESETROWS="50%,50%">
<FRAMESRC="cell.html">
<FRAMESRC="cell.html">
</FRAMESET>
<FRAMESETROWS="33%,33%,33%">
<FRAMESRC="cell.html">
<FRAMESRC="cell.html">
<FRAMESRC="cell.html">
</FRAMESET>
</FRAMESET>
上面这个例子产生了两行,而且第二行又分割成三列大小相等的空间。在第一个<frameset>tag中的50%,50%两项叁数是用来表是frame的大小。您可以给每个frame一个"名字"(name)。frame的名字在JavaScript语法中的地位非常重要。在本章的第一个范例中您已学到如何替frame命名。接下来您可以用<frame>tag告诉浏览器您要载入哪一个HTML文件。
我想您已了解frames的基本用法,接下来我们再看一个有趣的范例:
上面的按钮将显示:按某个frame中的按钮後,会在另一frame中写入文字。以下是此功能的原始码:在产生frames效果之前,您需先制作下列原始码(frames.html):
<HTML>
<HEAD>
<title>Frames</title>
</HEAD>
<FRAMESETROWS="50%,50%">
<FRAMESRC="frame1.html"name="fr1"noresize>
<FRAMESRC="frame2.html"name="fr2">
</FRAMESET>
</HTML>
以下是frame1.html的原始码:
<HTML>
<HEAD>
<scriptlanguage="JavaScript">
<!--Hiding
functionhi(){
document.write("嗨!<br>");
}
functionyo(){
document.write("!<br>");
}
functionbla(){
document.write("啦啦啦<br>");
}
//-->
</script>
</HEAD>
<BODY>
这是第一个frame!
</BODY>
</HTML>
以下是frame2.html的原始码:
<HTML>
<body>
这是第二个frame!
<p>
<FORMNAME="buttonbar">
<INPUTTYPE="button"VALUE="嗨"onClick="parent.fr1.hi()">
<INPUTTYPE="button"VALUE=""onClick="parent.fr1.yo()">
<INPUTTYPE="button"VALUE="啦"onCLick="parent.fr1.bla()">
</FORM>
</BODY>
</HTML>
哇!这些语法越来越长了!上述的语法是如何运作的呢?当使用者载入第一个档案(frames.html)後,将会产生两个frame,并且在第一个frame(命名为'fr1')中载入frame1.html,而在第二个frame(命名为'fr2')中载入frame2.html。到目前为止都只是普通的HTML语法。或许您已发现在frame1.html中包含了JavaScript语法,但此JavaScript并没有马上被执行。难到这些函式(functions)是不必要的?亦或是我得删除这些不必要的函式?虽然我是散惯的人,但这些函式确实是必须的。它们是被位於frame2.html中之JavaScript语法所呼叫而执行的。我在frame2.html中利用JavaScript语法制作了三个按钮,制作按钮来呼叫函式的方法我已在第一章提过,相信您对onClick的用法已相当熟悉。但是......parent.fr1是干嘛用的?若您对物件观念已相当了解,相信它对您不是甚麽新鲜事。您可以看到frames.html同时呼叫frame1.html与frame2.html两个档案,所以frames.html称为frame1.html与frame2.html的parent(请恕我直接用英文)。同理,这两个新的frame就称为frames.html的child-frames。您可将这种复杂的关系想像成阶层式架构(hierarchy)。以下我借助一个小'图'来厘清这种关系:
frames.htmlparent
/\
/\
/\
fr1(frame1.html)fr2(frame2.html)children
当然您可依此类推,产生一些'grandchildren'frames。(当然,这并不是正式的名称):
frames.htmlparent
/\
/\
/\
fr1(frame1.html)fr2(frame2.html)children
/\
/\
/\
gchild1gchild2'grandchildren'
若您想由frame2.html呼叫parent-frame中的任何函数,您只要将parent放在您欲呼叫函数名称之前即可。同理,若由parent-frame呼叫位於frame1.html中的函数,您只需将fr1放在被呼叫函数名称之前。为什麽用fr1呢?原因是我们在frames.html中开了两个frame,而且将它们分别命名为fr1和fr2。所以我用fr1代表第一个frame(frame1.html)。接下来的步骤就相当容易了。当我们欲由frame2.html(命名为fr2)呼叫第一个frame中的函式时该怎麽做?由上面的"小图"您可以发现,frame1.html和frame2.html之间并无直接关连(connection),因此您不可以"直接"由frame2.html呼叫位於frame1.html中的函式。您必须透过parent-frame来呼叫它,所以正确指标(index)应为parent.fr1。例如若您想由frame2.html呼叫hi(),您必须写成parent.fr1.hi()。这也就是为什麽frame2.html中的onClick要写成那种样子的原因了。对了!附带提一点小东西。您或许已发现本章中都用<scriptlanguage="JavaScript">代替前两章用的<scriptlanguage="LiveScript">。其实此二者间并没什麽差别。但起初JavaScript被植入Netscape浏览器时,您只能用LiveScript语法。(这是一种由Netscape发展的旧语法,和JavaScript极为类似)。我想既然我们讨论的是JavaScript函式,就应使用JavaScript语法。(这只是我的一己之见,在'JavaScript-society'中有许多关於LiveScript的讨论,目前也是众说纷纭....)
在此我要花一点时间讨论一个很多人关心的问题。当您观赏一个拥有数个frame的网页时,若您想link至internet其它网页,这些frame并不会消失而且会带来视觉上的干扰。这些讨厌的frame应该如何消除呢?您只要在您的<ahref...>tag中加入TARGET="_top"就可解决这个困扰。方法如下:
<ahref="goaway.html"TARGET="_top">如果您不想观赏我的网页了</a>
当然,您必须在您想要获得此效果的link中都加入TARGET="_top"。若想要整个网页中的link都有此效果,您可在此网页的head中加入<basetarget="_top">较方便。如此一来每个link被按下後都可将frame消除。
第四章
这章我将告诉您如何在状态列(statusbar)(也就是您浏览器最下方显示URLs的那一行)显示文字,并且将教您'跑马灯'(以下简称scroller)的工作原理。虽然以JavaScript完成的scroller目前仍有些问题(稍後会提到问题在哪儿?),但我还是告诉您它是如何写成的。首先,如何将文字填入statusbar呢?下述语法将告诉您如何做到这项功能:(按下按钮後请注视statusbar的变化)很新奇吧!请看看原始码:
<html>
<head>
<scriptlanguage="JavaScript">
<!--Hide
functionstatbar(txt){
window.status=txt;
}
//-->
</script>
</head>
<body>
<form>
<inputtype="button"name="look"value="写入文字"onclick="statbar('嗨!这就是状态
列(statusbar)!');">
<inputtype="button"name="erase"value="清除文字"onclick="statbar('');">
</form>
</body>
</html>
我制作了两个都会呼叫statbar(txt)函式(function)的按钮。当此函式被呼叫後,字串经由括弧中的变数txt传给statbar(txt)。(不一定要用txt,用别的变数名也可以)。当电脑执行到<form>tag时,一旦按下按钮就会呼叫statbar(txt)。但是电脑并没有马上将txt的内容写在statusbar,只是将欲显示的字串存入txt。换句话说,藉由呼叫函式,只是让变数txt得到一个值。因此当您按下'写入文字'这个按钮後,会呼叫statbar(txt)而且'嗨!这就是状态列(statusbar)!'这个字串会存入txt中。咻!讲了这麽多只是想告诉您这种写法可预留一些弹性。什麽弹性呢?就是您可重复使用txt这个变数。您看看第二个按钮,它也是呼叫相同的函式。若您不利用一个变数来传递字串的话,就必须写两个不同的函式了。那麽statbar(txt)到底做了些什麽?其实没什麽,只是将txt的内容写入变数window.status中。这是由window.status=txt;做的。另外若想消除文字,只需送一个空字串('')给statusbar。请注意,因为在onClick中我们已经使用双引号",所以这里必须用单引号'。这是为了让浏览器辨认哪两个引号是一对的,因此您必需双引号和单引号交替使用。由此份简介文件第二章您已学过onMouseOver的特性了:
<ahref="tpage.html"onMouseOver="window.status='Justanotherstupidlink...';returntrue">
您可能会对一件事感到厌烦。那就是当mouse的指标已从link移开了,但是statusbar中的文字还留在那!没关系,我教您一个解决的办法。利用上面教您如何消除statusbar中文字的方法,我们来写一个小函式。但是如何侦测出mouse的指标已从link移开并进而呼叫消除文字的函式呢?侦测mouse指标是否已从link移出的功能目前还无法达到,但可用"计时器"来暂时解决此问题。试试将mouse移到此link上看看statusbar的变化,但请不要按它。怎麽样?很棒吧!看看下面的原始码您就知到这东西很简单。
<html>
<head>
<scriptlanguage="JavaScript">
<!--Hide
functionmoveover(txt){
window.status=txt;
setTimeout("erase()",1000);
}
functionerase(){
window.status="";
}
//-->
</script>
</head>
<body>
<ahref="dontclck.html"onMouseOver="moveover('瞬间即逝!');returntrue;">
link</a>
</body>
</html>
这script的许多部份相信您已了解。moveover(txt)其实和先前的statbar(txt)差不多。erase()也和先前所讨论的相同。在HTML网页中的<body>tag里我们加入一个具有onMouseOver功能之link。当mouse指标移至"link"上就会呼叫moveover(txt),并且利用txt变数传递字串'瞬间即逝!'。接下来的步骤就和statbar(txt)一样,window.status收到txt的值後将之显示在statusbar上。而setTimeout(...)这项新函式是用来作为一个"定时器"。setTimeout(...)能作些什麽事呢?它的主要特性是当某段设定的时间"跑"完了之後,便执行某函式。在这个例子中,於1000毫秒後(也就是1秒後)就会执行erase()。换句话说,当1秒结束後moveover(txt)的功能就会因erase()的自动执行而停止。虽然规定时间"跑"完後定时器并不会重新启动,但您可以在erase()中再用一次setTimeout(...),使其循还不断,看起来就像一个跑马灯(scroller)。您已学到了setTimeout的功能和如何在statusbar中显示文字,接下我将教您如何制作一个在statusbar显示的"跑马灯"(scroller)。请按下方的按钮看看我做的scroller。由於script需由server载入到您的电脑中,因此这要花一点时间,请耐心等一下。
以下是原始码:
<html>
<head>
<scriptlanguage="JavaScript">
<!--Hide
varscrtxt="怎麽样!很酷吧!您也可以试试."+"Heregoesyourmessagethevisitors
toyourpagewill"+
"lookatforhoursinpurefascination...";
varlentxt=scrtxt.length;
varwidth=100;
varpos=1-width;
functionscroll(){
pos++;
varscroller="";
if(pos==lentxt){
pos=1-width;
}
if(pos<0){
for(vari=1;i<=Math.abs(pos);i++){
scroller=scroller+"";}
scroller=scroller+scrtxt.substring(0,width-i+1);
}
else{
scroller=scroller+scrtxt.substring(pos,width+pos);
}
window.status=scroller;
setTimeout("scroll()",150);
}
//-->
</script>
</head>
<bodyonLoad="scroll();returntrue;">
这里可显示您的网页!
</body>
</html>
上面script用的语法相信大部份您已经懂了。setTimeout(...)"告诉"计时器当时间到了就呼叫scroll()。如此一来scroller便会向前移动一步。在script的开头有许多计算式,那是用来决定文字开始显示的位置,了不了解并不重要。一旦决定了文字的启始位置,就必需加些空格(space)以使文字能显示在正确位置。
在此章一开始我曾提到,此种scroller并不是很受欢迎。即使是,也不会持续很久。为什麽呢?下面我列出几个主要原因:
当第一次看到scroller或许您会觉得很新奇,但久而久之便会觉得索然无味。当然,这是所有"酷玩意儿"(cooltrick)皆有的现象。其实这还不是主要原因,更严重的问题还在後头呢!当您移动mouse时,您可以发现scroller的速度改变了(至少在我的机器上是如此)。尤其当您更改setTimeout的值为使scroller跑快一点时,这种情况更严重。不过这问题或许还有解决方法。更糟的是若让scroller跑久一点,会出现Outofmemoryerror的问题!天呀!这是NetscapeNavigator2.0的一个"臭虫"(bug)。我们期待新的版本能更正此bug(译按:NetscapeNavigatorAtlasPreviewRelease已更正此bug)。在网路上有许多这方面的应用,您可以试着找找。我曾经看过有人将scroller放在Homepage中,这应该不会太难。(译按:有兴趣的人可叁考目录中本人所制做的scroller)
第五章
阵列(arrays)的运用是程式设计中一项种要的技术。每一种程式语言均以某种特定方式来表示阵列。或许您已了解阵列在程式设计中的好处,但翻遍Netscape所提供的文件,并没有提及如何使用阵列。这是因为JavaScript并不支援阵列。但是现在我将教您如何在JavaScript中使用阵列。首先,阵列是干用的?您可以把它看成一长串的变数(variables)。假设您现在需要宣告10个变数,您可以一个个将10个变数宣告为a,b,c...,但当您需要100个或更多的变数时,这种方法将会变得很麻烦。若您使用一个拥有10个元素(elements)的阵列(暂且命名为'MyArray')来表示这10个变数,则可以用MyArray[1],MyArray[2],MyArray[3]...分别代表第一,二,三....个变数(很多程式语言是从0开始当作第一个元素,但在JavaScript语法中是从1开始)。因此若您想将第一个元素(或称变数)的值指定为17,您只要写成MyArray[1]=17即可。由此可看出阵列的功用和一般变数是相同的。不光如此,若您想将所有元素的值均指定为17,您只要写一个简单的圈(loop)即可:
for(vari=1;i<11;i++)MyArray[i]=17
for-这个指令是告诉电脑其後的指令总共要执行几次。for-圈是从1开使,也就是电脑会先执行MyArray[1]=17。然後i会增加1并接着执行MyArray[2]=17。i每次递增1直到i=10为止。接下来教您如何做阵列的初始化(initialization)。这个问题曾在JavaScriptMailinglist中讨论过。(如果您想订阅mailinglist,您只要在e-mail中填入subscribejavascript-digest并寄到majordomo@obscure.org即可。接着您每天就会收到一到二个约20-30kB的大档案,这些档案包括所有来自JavaScript-list的信件)。
functioninitArray(){
this.length=initArray.arguments.length
for(vari=0;i<this.length;i++)
this[i+1]=initArray.arguments[i]
}
您不需要了解这个函式(function)的意义,您只要知道怎麽用就好。如果您要宣告一个拥有三个元素的阵列,且其值分别指定为17,18,19,您只要写成:varMyArray=newinitArray(17,18,19)。您也可以用字串(strings)当作元素的值:varheyho=newinitArray("This","is","酷")。因此您不必管元素值的型式(type),即使混着用也行:varMixedup=newinitArray(17,"yo",103)。下面我将对一个阵列'Mixedup'作初始化,并显示阵列的内容:
ElementNo.1:17
ElementNo.2:yo
ElementNo.3:103
其原始码如下:
<scriptlanguage="JavaScript">
<!--Hide
varMixedup=newinitArray(17,"yo",103);
document.write("ElementNo.1:"+Mixedup[1]+"<br>");
document.write("ElementNo.2:"+Mixedup[2]+"<br>");
document.write("ElementNo.3:"+Mixedup[3]+"<br>");
//-->
</script>
当我昨天写一个小游戏时,我遇到一个您也可能会碰到的问题。当您想清除视窗或frame中的内容时,Netscape文件中提到了一个函式可用--'document.clear()'。但当您将此函式写入网页中,它并不会如预期的清除视窗或frame中的内容。而且document.clear()在各种平台(platform)上似都无效。GordonMcComb告诉我一个清除视窗或frame中内容的好方法,您可以试试:
document.close();
document.open();
document.write("<P>");
您不一定要写最後一行document.write("<P>");,只有当您想在视窗中写入某些东西时才需要加入此行。上述方法对frame亦有效。
接下来我们谈一个可以让您在不同文件之间穿梭的语法--back()和forward()两个函式。通常我们在网页中加的back-link和Netscape-Navigator中的"Back键"功能上并不相同。Netscape-Navigator中的"Back键"是回到您historylist中的上一页。您现在也可利用JavaScript做到相同的功能。只要按下此link,您可以再度回到此页。JavaScript语法的原始码如下:
<html>
<body>
<FORMNAME="buttonbar">
<INPUTTYPE="button"VALUE="Back"onClick="history.back()">
<INPUTTYPE="button"VALUE="JS-Home"onClick="location='script.html'">
<INPUTTYPE="button"VALUE="Next"onCLick="history.forward()">
</FORM>
</body>
</html>
您也可以用history.go(-1)和history.go(1)代替.
第六章
许多网友问我一个有趣的问题:如何用mouse按一下便可同时载入两页文件。基本上有三种方法可以达到这种功能。第一种方法是制作一个按钮,让使用者按下後去启动一个能同时将两份文件载入不同frames或新视窗的函式(function)。若您曾经看过此份简介文件的其它章节的话,我相信您可以很轻易写出这种语法:我们制作了三个frame,第一个frame中包含了一个按钮。请注意,第一个HTML档案只是用来打开frame和给予每个frame一个名字。若您还不清楚JavaScript和frame的关系,可以先阅读第三章。不过在此还是照例让您瞧瞧原始码(不知您是否在很多电脑书籍中遇到一个相同的困扰,那就是作者常把一些自认很简单的东西忽略不提,结果那些东西正是读者搞不懂的地方!所以,若您对我提的东西已很了解,请发挥一下您的耐性:-)
frames2.html
<HTML>
<HEAD>
<title>Frames</title>
</HEAD>
<FRAMESETCOLS="295,*">
<FRAMESETROWS="100%,*">
<FRAMESRC="loadtwo.html"NAME="fr1">
</FRAMESET>
<FRAMESETROWS="75%,25%">
<FRAMESRC="cell.html"NAME="fr2">
<FRAMESRC="cell.html"NAME="fr3">
</FRAMESET>
</FRAMESET>
</HTML>
第一个frame会载入loadtwo.html并产生一个按钮:
loadtwo.html
<HTML>
<HEAD>
<scriptlanguage="JavaScript">
<!--Hiding
functionloadtwo(page2,page3){
parent.fr2.location.href=page2;
parent.fr3.location.href=page3;
}
//-->
</script>
</HEAD>
<BODY>
<FORMNAME="buttons">
<INPUTTYPE="button"VALUE="同时载入两份文件"onClick="loadtwo('frtest1.html',
'frtest2.html')">
</FORM>
</BODY>
</HTML>
按下按钮後,电脑会传递两个字串给loadtwo()并将之启动。由loadtwo()中可以看出,第一个字串是用来定义第二个framefr2所载入文件的位址和档案名。若您想定义另外的按钮来载入不同的文件,您可以重复使用此函式。只要将文件的URLs(addresses)传给loadtwo()即可。接下来谈谈用hyperlinks同时载入两页文件的第二种方法。在Internet上您可以发现许多网页使用<ahref="yourlink.html"onCLick="yourfunction()">来达到上述提及的功能。但此语法并不能在所有平台上均正常执行,因此最好不要用此语法。现在我告诉您另一种写法:我们可改用下述JavaScript语法:
<ahref="javascript:myfunction()">MyLink</a>
此种方式非常简单而且在所有浏览器中均能正常执行。您只要写上javascript:并加上您想联结的函式名即可。若此函式名称设为'loadtwo()',那您就可藉由按下此hyperlink来达到同时载入两份文件的目的了。再接着谈谈用mouse按一下便可同时载入两页文件的第三种方法,此方法可以以hyperlinks或按钮来执行。您可先在第二个frame中载入一个HTML文件:
<ahref="getfr2.html"target="fr2">请按这里!</a>
然後在此文件中(getfr2.html)加入onLoad这项指令,用来触发第三个frame载入另一份文件。如此一来便可同时载入两份文件。getfr2.html档的原始码如下:
<HTML>
<BODYonLoad="parent.fr3.location.href='getfr3.html';returntrue;">
文件内容.....。
</body>
</html>
当然,您必须在所有会被载入到第二个frame的文件中加入onLoad这项指令。另一个常遇见的问题是如何开一个新视窗并载入文件?我们想达到的效果是当使用者按一下mouse便会'弹'出一个新视窗。很简单,只要在<ahref...>中利用target这项特性就可达到此效果。例如:
<ahref="goanywhere.html"target="ResourceWindow">Go!</a>
现在我将谈谈在JavaScript中几种常用的运算子(operator)。运算子可以使您的JavaScript语法更精简。假设您想测试变数x是否大於3且小於10,您可写成:
if(x>3)
if(x<10)
doanything();
当满足x>3且x<10时,就会执行doanything()。还有一种更精简的写法:
if(x>3&&x<10)doanything();
'&&'称为AND-运算子。还有另一种被称为OR-运算子的东东可让您用来检视是否变数x等於5或变数y等於17:
if(x==5||y==17)doanything();
当满足x==3或y==17时,就会执行doanything()。当然,当两者皆成立时也会执行doanything()。在JavaScript中是利用==来做比较的工作(其它尚有<,>,<=和>=),这些都和C/C++的语法相同。另外单一'='是用来将数值存入变数用的。(在Pascal语法中将数值指定给变数是用:=,而做比较是用单一的'=',这和JavaScript语法有点不同)若您想利用'不等於'这项特性,您可以用!=。例如:x!=17.尚有许多可以精简您的JavaScript语法的运算子,去翻翻Netscape的文件吧!
第七章
输入表单(form)对某些Internet上的网页而言是很重要的。通常form的输入内容会被送回server中做处理。JavaScript具有确认输入值的功能,可以事先确保这些值是属於"合法的",进而避免将错误的输入值送回server。首先我将告诉您如何对form的输入做确认的工作,再来我将会提到用JavaScript将资料送回server的可能性。咱们开始吧!我先写一个简单的语法。在下面我加了两个text-元件(element),请将您的大名写入第一个空格,并将您的e-mailaddress写入第二个空格。您可在这两个空格中任意输入并按下按钮。您也可以不输入任何东西就按下按钮试试!
请输入您的大名:
请输入您的e-mailaddress:
对第一个空格而言,若您没有键入任何东西,电脑便会出现一个错误讯息,并请您再输入一次。当然,此空格会把任何输入的字串都视为"合法的"输入,它无法辨认出您输入的名字是正确的或是胡的。即始您输入的是数字,它也会把此数字当成您的大名。例如您输入'17',它将会显示'嗨!17'。第二个空格就设计得稍微复杂一点了。您可试着输入一个简单的字串-例如您的大名,它将会显示错误讯息,并请您再输入一次(除非您输入的字串含有@...)。这个空格的确认标准是检视您输入的字串中是否含有@。即使只输入一个@,它也会被视为合法的输入---虽然这也不是正确的e-mailaddress。所有Internet的e-mailaddress皆含有@,因此对e-mailaddress输入值做此种确认工作是很适合的。接下来看看上述功能的原始码吧:
<html>
<head>
<scriptlanguage="JavaScript">
<!--Hide
functiontest1(form){
if(form.text1.value=="")
alert("您没写上任何东西,请再输入一次!")
else{
alert("嗨"+form.text1.value+"!您已输入完成!");
}
}
functiontest2(form){
if(form.text2.value==""||
form.text2.value.indexOf('@',0)==-1)
alert("这不是正确的e-mailaddress!请再输入一次!");
elsealert("您已输入完成!");
}
//-->
</script>
</head>
<body>
<formname="first">
Enteryourname:<br>
<inputtype="text"name="text1">
<inputtype="button"name="button1"value="输入测试"onClick="test1(this.form)">
<P>
Enteryoure-mailaddress:<br>
<inputtype="text"name="text2">
<inputtype="button"name="button2"value="输入测试"onClick="test2(this.form)">
</body>
先看看body-之後的HTML语法。我们嵌入了两个text元件和两个按钮。第一个按钮呼叫test1(...),第二个按钮呼叫test2(...)。this.form这个变数会将此form的名字(在此例中就是first)传给函式(function),以便能正确将元件"定址"(address)。test1(form)的功用在於检查您是否输入字串(亦即检查是否为"空字串")?此项工作是由if(form.text1.value=="")...所执行。'form'这个变数将会接收由'this.form'所传来的值。但我们如何在test1(...)中抓取我们所输入的字串呢?您可利用'value'这个变数再加上'form.text1'来抓所输入的字串。然後将它和""比较,检查是否为"空字串"。若是"空字串"则表示并无输入任何东西,那麽Netscape将会出现警告并要求您再输入一次。若test1(...)检查结果并非"空字串",则会出现"您已输入完成!"的讯息。请注意,即使只输入一个空白(space),test1(...)也会将之视为合法输入。当然,您也可以略施小技来排除上述可能性,我相信这很容易。现在请看test2(form)。在此函式中我们利用相同的方法来检测输入值是否为空字串,但是我在if-指令中加入了额外的检测功能。||这个符号代表OR运算子(operator),您可在第六章中学习它的用法。if-指令用来检测第一与第二个比较式是否其中之一为"真"?若有其中之一为"真",则整个if-指令即为"真",如此便会执行其後的指令。换句话说,若您没有输入任何字串或您输入的字串中没有包含'@',均会被视为"不合法"输入。您知到有几种方法可用来送出form的内容吗?最简单的方法就是利用e-mail来送出form的内容。我下面介绍的方法就是属於这一种。若您不想利用e-mail来送出form的内容且想让server能自动处理form的输入值,此时此刻只有CGI能做得到。譬如您想做一个类似Yahoo可以让使用者迅速得到结果的搜寻引擎(searchengine),您就必须使用CGI。如此一来使用者才不需等待系统管理者处理form的输入值,而可由server自动处理并迅速将处理结果报告给使用者。目前JavaScript无法达到此种功能。即使您想制做一个"访客签名簿"(guestbook),也不可能利用JavaScript来叫server自动将资页中。目前只有CGI能做到如此。但您可以制做一个利用e-mail传送使用者资料的guestbook,只是您需以手动(manual)方式来处理使用者所传来的资料。若您一天不是收到很多使用者送来的资料的话,这也未尝不可。以下语法只使用到普通的HTML语法,并不需用到JavaScript!只有当您想在资料送出前做一些确认工作的话,才需用到JavaScript。虽然目前有些浏览器无法使用mailto-这项指令,我相信较新版的浏览器都会支援这个指令。
<FORMMETHOD=POSTACTION="mailto:your_email@goes.here">
<H3>您喜欢我的网页吗?</H3>
<INPUTNAME="choice"TYPE="RADIO"VALUE="1">一点也不喜欢。<BR>
<INPUTNAME="choice"TYPE="RADIO"VALUE="2"CHECKED>简直浪费我的时间。<BR>
<INPUTNAME="choice"TYPE="RADIO"VALUE="3">这简直是Net上最烂的站台。<BR>
<INPUTNAME="submit"TYPE="SUBMIT"VALUE="Send">
</FORM>
上述语法可藉由e-mail收到使用者对您网页的观感。唯一的困扰是您可能会收到内容类似密语(cryptic)的mail。mail内容的空格(space)有时会以'+'代替,有时会以'%20'代替。看+起+来+就+像+这+样。我相信网路上应有某种程式可将收到的mail转换成"可读"的语句。
另外有一种不错的应用可使您的表单输入更具"亲和性"(user-friendly)。您可以指定一开始先"定焦"(focus)於哪个元件(element,简单的说就是输入项)。或是您可让浏览器"定焦"於使用者输入错误的表单。换句话说,浏览器将会把mouse的游标放在您"定焦"的元件上,如此一来使用者便不需在输入字串之前按一下mouse。请看这项功能的原始码:
functionsetfocus(){
document.first.text1.focus();
return;
}
这项语法是将"定焦"放在第一个text-元件上(以本章为例,就是在"请输入您的大名"的空格中有游标在闪烁)。您必需在语法中指定您想"定焦"的表单名字(以本章为例,就是first)和元件的名字(以本章为例,就是text1)。若您在一开始载入网页时就想"定焦"於某个元件上,只要在<body>-tag中利用onLoad-即可:
<bodyonLoad="setfocus()">