Javascript高级教程 - 第三课

转载 2007年09月21日 10:05:00
 第一页:Javascript高级教程 - 第三课

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

随着我们所掌握的JavaScript日渐丰富,我们可以编制出越来
越复杂的应用程序。上次的课程中我们学习了如何利
用JavaScripts编写Cookies。今天我们将学习如何加入定时
功能。给时间定时的能力在3.0版的浏览器中非常有用,而在更
新的浏览器中则会在动态HTML应用中发挥更大的功用。

如果你用的是Netscape 4.0或微软的IE 4.0,你可能回注意到
动态HTML可以在页面中移动不同的内容。在JavaScript中将某
个物体在屏幕中移动需要用到一个循环(loop),用循环的功
能使物体随着时间推移移动。但是你如何告诉JavaScript将某
个物体每秒钟或者每10分之一秒移动一点呢?

然而在不同的浏览器中将某物体进行移动的能力有很大的差别。
要想在不同的浏览器中都可以应用动态HTML的东西,你需要做
一些特别的处理。所以在讲解完事件定时之后我将讲解如何识
别用户所使用的是何种浏览器(针对不同的浏览器你可以使用
不同的程序代码)。

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


第二页:如何给事件定时


第四页:定时循环的做法

第五页:一个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_stringsetTimeout的引号中拉出来,由于
该变量变量目前不在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按钮常会把你带到你不想去的网页。

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

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给事件定时很容易。其关键指令是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程序了。

一点都不好

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

相关文章推荐

andriod第三课----java高级语法2

static 关键字1.static 不能用于修饰构造器2.静态方法是属于类的,静态成员也是属于类的,类一加载就存在。引用时不需要创建对象再用, 而可以直接“类名.方法或成员”3.只要类在,他就在,可...

再学JavaScript-第三课-函数

一、定义方式 function语句式:可以提前调用,对于function语句式的函数,JavaScript解析器会优先解析。 函数的直接量 function构造函数式 var f = new Func...

javaScript第三课-other标签、正则表达式及常用标签回顾

1、label标签:用于给各元素定义快捷键 当把标签设置在整行上 则在该行任意位置点击都能在文本框中现光标。 2、pre标签:将数据放到pre中能保持原来的格式,比如换行和空格都会和输入的相对位...

java教程 第三课-1

  • 2012年06月07日 10:10
  • 643KB
  • 下载

java程序员第三课 javaScript基础&DOM

1、上节课内容回顾 * html里面form表单* css* javascript 2、内容补充 1、js和html两种结合方式 * 使用外部文件方式 ...

java教程 第三课-2

  • 2012年06月07日 10:11
  • 680KB
  • 下载

JavaScript第三课——数据类型(typeof操作符、Undefined类型、Null类型、Boolean类型)

学习要点: 1.typeof 操作符 2.Undefined 类型 3.Null 类型 4.Boolean 类型  ECMAScript 中有 5 ...

龙哥制作电脑病毒第三课教程

  • 2013年03月15日 18:12
  • 7.72MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Javascript高级教程 - 第三课
举报原因:
原因补充:

(最多只允许输入30个字)