分享
 
 
 

Javascript高级教程 - 第三课

王朝asp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

第一页:Javascript高级教程 - 第三课

事件的定时以及浏览器的识别

随着我们所掌握的JavaScript日渐丰富,我们可以编制出越来

越复杂的应用程序。上次的课程中我们学习了如何利

用JavaScripts编写Cookies。今天我们将学习如何加入定时

功能。给时间定时的能力在3.0版的浏览器中非常有用,而在更

新的浏览器中则会在动态HTML应用中发挥更大的功用。

如果你用的是Netscape 4.0或微软的IE 4.0,你可能回注意到

动态HTML可以在页面中移动不同的内容。在JavaScript中将某

个物体在屏幕中移动需要用到一个循环(loop),用循环的功

能使物体随着时间推移移动。但是你如何告诉JavaScript将某

个物体每秒钟或者每10分之一秒移动一点呢?

然而在不同的浏览器中将某物体进行移动的能力有很大的差别。

要想在不同的浏览器中都可以应用动态HTML的东西,你需要做

一些特别的处理。所以在讲解完事件定时之后我将讲解如何识

别用户所使用的是何种浏览器(针对不同的浏览器你可以使用

不同的程序代码)。

先学习事件的定时。点击下面的按钮,3秒钟后将弹出一个提

示框。

第二页:如何给事件定时

在Javascript给事件定时很容易。其关键指令是setTimeout()

和clearTimeout()方法。利用setTimeout(), 指令可以在未来

的某个指定时间执行特定指令。如果你改变主意,你可以用

clearTimeout()取消setTimeout的定时.

下面是setTimeout的基本格式:

var the_timeout = setTimeout("some javascript

statement", some_number_of_milliseconds);

在上面的例子中用到的指令如下:

var the_timeout = setTimeout("alertAndRedirect ();",3000);

该语句中有3项重要内容:

setTimeout返回一个值。在该语句中

the_timeout是一个变量,它指向特定的setTimeout。

如果你想取消该setTimeout的定时,你只需引用该变量

即可。你可以给变量起一个别的名称。

在setTimeout中用到的第1个变量是一个JavaScript 语句的字

符串。

在本例中第1个参数是字符串:"alertAndRedirect();"

alertAndRedirect是为载入一个提示框而编写的一个函

数,当用户点击“OK”时还重新回到本页面。

注意在引号中的内容是一个完整的JavaScript语句,带有

分号和其他必须的语法. 如果你执行该段代码则会调用函

数alertAndRedirect。setTimeout只规定了该语句出现的

时间。

以下是函数alertAndRedirect()的代码:

function alertAndRedirect()

{

alert('ok! exhale!');

window.location.replace("timing.htm");

}

setTimeout的第2个参数指定了在多少毫秒之后执行第1个参数。

一秒钟等于1000毫秒。所以如果你想让某事在秒钟之后发

生你必须将第2个参数设置为3,000 毫秒。

我们可以做下面的练习熟悉它的工作原理:

第三页:定时循环的概念

其制作方法就是让按钮的onClick事件调用以下函数:

function ringBell()

{

var timer1 = setTimeout("window.document.the_form.the_text.value='3 seconds!';",3000);

var timer2 = setTimeout("window.document.the_form.the_text.value='6 seconds!';",6000);

var timer3 = setTimeout("window.document.the_form.the_text.value='9 seconds!';",9000);

}

它的意思是,“从现在开始,三秒钟后显示‘三秒’,六秒钟

后显示‘六秒’,九秒钟后显示‘九秒’”,很好理解,对吧?

但是,下面这样却不行:

function doDumbTimer()

{var timer1 = setTimeout("window.document.the_form.the_text.value='3 seconds!';",3000);

var timer2 = setTimeout("window.document.the_form.the_text.value='6 seconds!';",3000);

var timer3 = setTimeout("window.document.the_form.the_text.value='9 seconds!';",3000);

}

试一下这个错误的定时代码看看会发生什么?

faulty timer code?

请注意当你等了三秒钟,三个定时信息之一神秘地出现在文

本框里,然后就停在那儿。在上面的不好的代码中,每个

setTimeout都连续地执行,(就是“从现在开始,三秒钟

后显示‘三秒’,三秒钟后显示‘六秒’,三秒钟后显示

‘九秒’”)。所以当三秒钟以后,三件事儿都发生了,你

得到的正好是其中最后发生的结果----当然不是你希望的

结果。

一旦你理解了,setTimeout()还是相当容易使用的。但是

一个难点儿的问题提出来了:你如何去做一个定时器,让某

件事每隔2秒钟就发生一次,从现在一直到永远?象这个例

子:

先别担心停止定时器按钮,稍后我会讲clearTimeouts。只

要想想你怎么能够让定时器无限循环。实际上这是一个非常

重要的问题而不仅仅是一个小练习。就象我前边提到的那样,

当你用动态HTML让什么东西缓缓地在屏幕上移动时,就执行

一个定时循环:“轻轻移动一点,等待,再移动一点,再等

待.....如此这般”

你想到这个问题了吗?

好,答案并非那么简单。你无法象上面的那个例子那样,只

用一个函数,就能够每隔两秒就改变文本框的内容,象这样:

function theTimer()

{

var timer1 = setTimeout("changeTextBoxTo(2);",2000);

var timer2 = setTimeout("changeTextBoxTo(4);",4000);

var timer3 = setTimeout("changeTextBoxTo(6);",6000);

var timer4 = setTimeout("changeTextBoxTo(8);",8000);

var timer5 = setTimeout("changeTextBoxTo(10);",10000);

.

.

.

}

因为,好,你可以看出为什么不行:如果你想用这种方法让

某件事无限循环下去,你必须有无限多行的代码。相比起其

它问题,比如敲得你肩酸背痛来说,光是下载一个包含了无

限多行javascript的页面就需要太长的时间,所以,这种方

法根本就谈不上是一种选择。

这个也不行,虽然它看起来更酷一些:

function theTimer()

{

the_time = 0;

hellIsHot = true;

while (hellIsHot == true)

{

the_time += 2;

var timer = setTimeout("changeTextBoxTo(the_time);", the_time*1000);

}

}

请把程序研究一会,看看会得到什么结果。但不要尝试去运

行它,否则结果会使你很不愉快。让我们在“while"循环中

走几趟:

第一遍

while (hellIsHot == true) : 是的地狱还

是热的。

the_time += 2 : 所以现在 the_time = 2

var time = setTimeout("changeTextBoxTo(2);", 2000) :

所以, 从现在开始两秒后, 文本框变成了“2.",这正是我们想要的结果。

第二遍

while (hellIsHot == true) : 确实,地狱还是热的.

.

the_time += 2 : 所以现在 the_time = 4

var time = setTimeout("changeTextBoxTo(4);", 4000) :

所以, 从现在开始四秒后, 文本框变成了“4.",很好。

第三遍

while (hellIsHot == true) : 不, 地狱一

点也没凉快.

the_time += 2 : 所以现在 the_time = 6

var time = setTimeout("changeTextBoxTo(6);", 6000) :

所以, 从现在开始六秒后,

文本框变成了“6.",好。

第四遍

while (hellIsHot == true) : 是的,还是

热的。

还那样

还那样

你看明白了。这段代码看起来象是做对了。不幸的是其实不

是这样。相反它创建了一个死循环,一直设定setTimeouts

直到地狱冷下来。这里有两个问题。首先,当在循环里时,

你的浏览器就无法做任何其它的事情,基本上就是停止,执

行动作,再设定下一个定时器,一直到永远。第二,每次设

定setTimeout时,浏览器 都要记住你预定执行的内容以及

何时执行。最终你的浏览器会把内存耗尽,这时你的浏览器

会崩溃,或者你的计算机会崩溃,或者把你弄疯而永远也不

想再写一行Javascript程序了。

一点都不好

幸运的是,有一种方法能够写出成功的定时器循环。

第四页:定时循环的做法

要使定时器循环工作你需要写一个函数实现循环调用。这里是

一个例子:

var the_count = 0;

var the_timeout;

function doTimer()

{

window.document.timer_form.the_text.value = the_count;

the_count += 2;

the_timeout = setTimeout("doTimer();", 2000);

}

这里用到的定时器就是上一页所用的定时器。当用户点击按钮

时就调用该函数。该函数将the_count的当前值写到文字框中。

然后the_count增加2,则开始调用函数自身。文字框中的数值

也相应更新,the_count在增加2, 则再次调用函数自身。在等

待的这两秒期间浏览器则可以执行其他的同步工作。the_count

一增加2就执行另一次setTimeout()。你不用担心会造成内存

崩溃,因为在给定时间内只有一个setTimeout()在执行。

而无限的"while" 循环则会锁定浏览器的工作,在执行该循环

的过程中浏览器不能同时执行别的任何指令。而setTimeout则

可以使循环的间隙中让浏览器执行别的工作。

如何取消setTimeout

现在你已经学习了如何设置一个无限循环。但是你必须懂得如

何终止循环。其指令就是clearTimeout。上例中定时器还有下

面这个表单元素:

<input type="button" value="stop timer"

onClick="clearTimeout(the_timeout);">

点击这个按钮就可以终止定时器。指令是clearTimeout(),其

实很简单,如果你这样设置setTimeout,

the_timeout = setTimeout("some javascript",3000);

你可以这样取消定时器:

clearTimeout(the_timeout);

很简单,对吧?下面我们看一个复杂循环定时器,一个可以报

告时间的定时器。

第五页:一个Javascript编写的时钟

现在时间是:

点击“启动时钟”则时钟开始运行。它从你的计算机中读取时间

并每半秒更新一次文字框中的显示。这个例子通过一个自调用

的函数设置了一个定时器。同时这个例子可以让你了解一点Date

对象的功能。当讲解cookies时,我提到过Date对象。

以下是代码:

function writeTime() {

// 获得日期对象

var today = new Date();

// 从对象中获得信息

var hours = today.getHours();

var minutes = today.getMinutes();

var seconds = today.getSeconds();

// fixTime 使分和秒可以正常显示

// 对于小于10的数字则在该数字前加一个0

minutes = fixTime(minutes);

seconds = fixTime(seconds);

//将时间字符串组合在一起并写出

var the_time = hours + ":" + minutes + ":" + seconds;

window.document.the_form.the_text.value = the_time;

//每半秒钟执行一次该函数

the_timeout= setTimeout('writeTime();',500);

}

function fixTime(the_time) {

if (the_time <10) { the_time = "0" + the_time; } return the_time; }

我们仔细研究一下代码。

var today = new Date();

正如new Array() 可以生成一个新的数组,你可以可以

用new Date() 生成一个新的日期对象。生成对象之后,

你可以对其提出你的问题。你生成的新的日期对象的括号

中间没有任何参数, 但JavaScript会查询计算机的始终

并用其生成新的日期对象。现在我们的日期对象名为

"today" ,我们可以从中提取相应的信息。

var hours = today.getHours();

这条用于获得当前的小时值。它是军队格式的时间,即,

如果当前时间是下午两点,则它返回的值是14。getHours()

是Javascript的日期对象内置的方法调用。

var minutes = today.getMinutes(); var seconds = today.getSeconds();

这几行原理和getHours()类似。

minutes = fixTime(minutes);

getMinutes存在一些问题,如果分钟是11:01, getMinutes

将返回 "1"。时钟的显示格式可不是这样,它应该显示为

“01”。fixTime函数就是用于执行纠正显示格式的功能。

下面两行将字符串组合在一起并显示出来,

the_timeout = setTimeout('writeTime();', 500);

设置没半秒执行一次该函数的循环。

下面我们将学习如何在定时器中加入变量。

第六页:给定时器加入变量

定时器的功能主要在于设定某个未来的时间,让Javascript到

时执行某个语句:

var the_string = "hello";

the_timeout = setTimeout("alert(the_string);", 60000);

这两行指令让JavaScript等待一分钟然后弹出一个提示框显

示the_string变量所包含的内容。所以一分钟后JavaScript就

寻找叫做the_string的变量并调用alert()。但是问题是一分钟

后该变量中所包含的内容可能后是别的什么。所以如果你把这

两行代码放在一个函数内,setTimeout有可能会报错。例如在

下例中:

function alertInAMinute()

{

var the_string = "hello";

the_timeout = setTimeout("alert(the_string);", 60000);

}

然后你在某个链接中调用这个函数:

<a href="#" onClick="alertInAMinute(); return false;">blah!</a>

可能会出错。因为你定义名为the_string的变量时用的是var,

而当你在一个函数内使用var时,Javascript将其理解为该变量

只存在于该函数中。一旦离开该函数而进入另一个函数后,该

变量就会从Javascript的记忆中消失。所以当后来需要调用该变

量时,Javascript从它的记忆中是不可能找到该变量的,错误因

此就产生了。

产生问题的原因在于你将一个变量传递给setTimeout。你可以通

过将变量的值而不是变量本身传递给setTime来避免这个问题:

function alertInAMinute()

{

var the_string = "hello";

the_timeout = setTimeout("alert(" + the_string + ");",60000);

}

这段代码将变量the_string从setTimeout的引号中拉出来,由于

该变量变量目前不在setTimeout的引号内,JavaScript就可以从

记忆中找到该变量的值。

定时器在动态HTML中用途非常广泛,所以值得你仔细研究它。

要使所有的拥护都能看到动态HTML的内容,你必须了解如何识别

用户所使用的浏览器。

第七页:识别用户的浏览器

我所讲到的大部分内容都可以在支持JavaScript的浏览器中

运行。但是在某些浏览器上有些功能却不能正常执行。MSIE

3.0就不支持图片替换。

有几种办法可以处理 不同的浏览器。最简单的就是首先确定

用户所用的浏览器是什么类型,然后根据浏览器的类型执行相

应的指令。

有些网站直接让用户选择自己的浏览器类型然后执行相应的

指令。但这样并不是一个好办法。用户通常很反感这种让自己

自报家门的事情。同时针对用户所使用的浏览器的版本的不同

你必须做出不同版本的网页。

而用JavaScript就可以识别用户使用的是何种浏览器,然后自

动将用户导引到支持用户浏览器的网页。但这种方法仍须迫使

你为一个页面做出不同的若干个版本并随时进行更新。

更好的办法是让你的网页更聪明,让它针对不同的浏览器显示

不同的内容。

第八页:如何识别用户的浏览器

每种浏览器除了有Document(文件)对象之外还有

Navigator对象,Navigator有两个属性包含着你所使用的浏览

器类型的所有信息:appName and appVersion.

appName是浏览器的类型,如果你用的是Netscape的某种版本,

你的Javascript中可以加入这样一行:

var the_browser_name = navigator.appName;

则the_browser_name的值是 "Netscape"。对于 MSIE,

则the_browser_name是"Microsoft Internet Explorer" 。所以

如果你想知道某人用的何种浏览器就可以用appName。

appVersion是浏览器的版本.其显示信息例子:"4.03 [en]

(Win95; I)"。意思是Netscape version 4.03, English

International, for Win95/NT。将版本号从中提取出来的办法

很简单:只需抓取第1个数字即可。最快捷的办法就是使用函

数parseFloat(),它将字符串中第1个数字符号提取出来并返回

数值:

var the_browser_version = navigator.appVersion;

var the_version_number = parseFloat(the_browser_version);

除了版本号之外appVersion别的信息都不是很确切。不同的浏

览器可能会在该字符串中加入各种希奇古怪的东西。

现在我们利用以上获得的信息作一些有用的事。点击下面的按

钮你会看到Navigator最直观的用途。

以下是用到的两个函数。点按钮调用

browserSizeUp():

function browserSizeUp()

{

var browser = navigator.appName;

var version = versionNumber();

var the_string = browser + " " + version;

if ((browser == "Netscape" || browser == "Microsoft Internet Explorer") &&

(version >= 4))

{

alert("The browser doctor says: " + the_string + "? Now that's a beautiful browser!");

} else {

alert("The browser doctor says: " + the_string + ", Hmm. Maybe it's time to upgrade.");

}

}

function versionNumber() {

// return version number (e.g., 4.03)

return parseFloat(navigator.appVersion)

}

会发生什么呢?如果我们检测到的用户的浏览器版本大于4,则

显示一个提示框,否则就显示另外的提示框。在实际的应用中

你常常需要用到document.writeln() 生成适应不同浏览器的

HTML。

用户所看到的页面内容取决于它所使用的浏览器,浏览器的

版本。随着浏览器版本不断增多,又分别应用于不同的操作

平台,你要想浏览器的变化随时保持同步的困难不断加大。

所幸的是还有一种办法可以避免这个问题。

第九页:对象和方法的识别

最佳的方法是你先确定某一段代码具备什么功能,然后搞清楚

浏览器具备什么功能。

例如,我们知道有些浏览器支持图片替换,有些则不行。好在

可以检测浏览器是否具备这种功能:只需检测浏览器是否具

有document.images对象即可:

if (document.images)

{

do lots of image swap stuff

}

这样图片替换的代码就只会在支持图片替换的浏览器中才执行。

这种技巧还可以用于方法和函数。不是所有的;浏览器都有各

种方法。例如,在Netscape 4中,你可以用window.moveTo()方

法将窗口在屏幕中移动,如果你想在调用该方法之前先检测浏

览器是否具有这种方法,则:

if (window.moveTo)

{

make that window fly

}

确保浏览器支持某项功能后再调用该功能可以避免很多无谓的

脚本错误。使用浏览器功能测试的方法而不是浏览器类型测试

的方法可以使你的网页内容同各种平台上各种类型各种版本的

浏览器都保持同步。

第十页:History对象

在Javascript对象结构中还有两项我们没有涉及,即Packages

和History。要了解Packages需要先学习Java,但History则

是JavaScript特有的而且非常有用。

History包含着你的浏览器访问过的URL的记录列表.History对

象使你能利用window.history.back()

window.history.forward()在列表各项记录中来回切换。back

的功能和你的浏览器上的back按钮的作用是一致的。

这两种方法在帧(分割窗口)中非常有用,因为在帧中浏览器

的back按钮常会把你带到你不想去的网页。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有