当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JS教程:线小测试程序

Javascript
用JavaScript实现浏览器地震效果
Javascript实例教程(8) 利用Javascript基于浏览器类型的重定向
Javascript实例教程(14) 鼠标触发窗口
使主页呈现“飞舞”特效
Javascript实例教程(21) OLE Automation(1)
Javascript实例教程(13) 鼠标移过时报警
Javascript实例教程(10) 随机显示图片
Javascript实例教程(2) 创建弹出式窗口
JavaScript 小技巧(第十集)
Javascript实例教程(3) 创建折叠式导航菜单
Javascript实例教程(7) 利用Javascript进行密码保护
完美解决一个事件激活多个函数(2)
Javascript模拟游戏中的弹出菜单效果
Javascript实例教程(6) 在一个表单中设置和检查Cookies
JavaScript 小技巧(第八集)
Javascript实例教程(4) 探测浏览器插件
JavaScript 小技巧(第九集)
JavaScript学习:基础继承机制
初学Javascript之cookie篇(译)
让弹出窗口变得“体贴”一些(javascript)

Javascript 中的 JS教程:线小测试程序


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 85 ::
收藏到网摘: n/a

9.3  在线小测试程序

在本章中,我们将对“在线小测试”程序作两处修改。一是允许用户首先选择回答完问题所需要的时间,二是允许用户选择要回答多少个问题。

要把“在线小测试”程序转换为一个基于计时器的程序,只需修改两个页面,即QuizPage.htm页面和GlobalFunctions.htm页面。

首先,需要修改的是QuizPage.htm页面中小测试程序的开始表单,在新的程序中,将允许用户选择要回答多少个问题以及答题的时间限制。接下来,还要修改cmdStartQuiz_onclick()函数,使得当在cmdStartQuiz_onclick()函数中调用resetQuiz()函数时,能够传入两个参数,一个参数表示答题的时间限制,另一个参数表示用户选择回答问题的数量。其中,resetQuiz()函数是定义在GlobalFunctions.htm页面中的。

现在,我们讨论一下GlobalFunctions.htm页面本身,在GlobalFunctions.htm页面中,需要修改resetQuiz()函数,以便根据用户选择的时间限制启动一个计时器。另外,还需要创建两个新的函数,以便对计时进行显示和处理:一个函数将在浏览器窗口的状态栏中显示剩余的时间以便提示用户,另一个函数将处理当计时器到点时的情况。

首先,我们来修改QuizPage.htm页面,将QuizPage.htm页面在文本编辑器中打开。

在QuizPage.htm页面中,frmQuiz表单目前仅包含一个按钮,将该表单修改为如下所示的代码:

<form name="frmQuiz">

<p>

Number of Questions <br>

<select name="cboNoQuestions" size="1">

<option value="3">3

<option value="5">5

</select>

</p>

<p>

Time Limit <br>

<select name="cboTimeLimit" size="1">

<option value="-1">No Time Limit

<option value="60">1 Minute

<option value="180">3 Minutes

<option value="300">5 Minutes

</select>

</p>

<input name=cmdStartQuiz type=button value="Start Quiz"

onclick="return cmdStartQuiz_onclick()">

</form>

在该表单中,添加了两个新的<select>标记,以创建两个下拉列表框。第一个下拉列表框允许用户选择愿意回答多少个问题,第二个下拉列表框则允许用户设置回答问题的时限。

接下来,修改页面顶部的cmdStartQuiz_onclick()函数。

<script language=JavaScript>

function cmdStartQuiz_onclick()

{

var cboNoQuestions = document.frmQuiz.cboNoQuestions;

var noQuestions =

cboNoQuestions.options[cboNoQuestions.selectedIndex].value;

var cboTimeLimit = document.frmQuiz.cboTimeLimit;

var timeLimit = cboTimeLimit.options[cboTimeLimit.selectedIndex].value;

window.top.fraTopFrame.fraGlobalFunctions.resetQuiz(noQuestions,

timeLimit);

window.location.href = "AskQuestion.htm";

}

</script>

cmdStartQuiz_onclick()函数被连接到了cmdStartQuiz按钮的onclick事件处理器,以便用户启动在线小测试程序。在上一版本的在线小测试程序中,仅仅调用了位于全局模块中的resetQuiz()函数,并加载AskQuestion.htm页面。现在,我们需要获取用户在下拉列表框中选中的问题数量和时间限制。后面我们还将看到,resetQuiz()函数也做出了相应的修改,以便接收两个参数—— 用户选择的问题数量和时间限制。

在cmdStartQuiz_onclick()函数中,定义了变量cboNoQuestions以引用表单中的cboNoQuestions下拉列表框,cboNoQuestions控件就是供用户选择回答多少个问题的下拉列表框。使用变量cboNoQuestions可以避免对document对象和表单对象的冗长引用,使得代码保持简洁易读。

在cmdStartQuiz_onclick()函数的第二行代码中,获取了cboNoQuestions下拉列表框中所选中的值,即用户选择要回答多少个问题,并将该值保存在变量noQuestions中。

随后的两行代码完成了类似的功能,用变量cboTimeLimit来引用表单中的cboTimeLimit下拉列表框,然后获取了cboTimeLimit下拉列表框中所选中的值,即用户所选择的回答问题的时间限制,并将该值保存在变量timeLimit中。

在接下来的那行代码中,复位了小测试程序,并将两个参数noQuestions和timeLimit传递给window.top.fraTopFrame.fraGlobalFunctions.resetQuiz()方法。其中,参数noQuestions表示问题数量,参数timeLimit表示时间限制。

这样就完成了对QuizPage.htm页面的修改。将该页面进行保存后,即可关闭文本编辑器。

现在,我们将注意力转移到GlobalFunctions.htm页面,首先来看一下需要修改的resetQuiz()函数,相应代码如下所示:

function resetQuiz(numberOfQuestions, SelectedTimeLimit)

{

timeLeft = SelectedTimeLimit;

totalQuestionsToAsk = numberOfQuestions;

var indexCounter;

currentQNumber = -1;

questionsAsked = new Array();

for (indexCounter = 0; indexCounter < questions.length;indexCounter++)

{

questionsAsked[indexCounter] = false;

}

numberOfQuestionsAsked = 0;

numberOfQuestionsCorrect = 0;

if (timeLeft == -1)

{

window.status = "No Time Limit";

}

else

{

quizTimerId = window.setInterval("updateTimeLeft()",1000);

}

}

首先修改的是resetQuiz()函数的定义。在上一版本的在线小测试程序中,resetQuiz()函数并不接收参数。现在,resetQuiz()函数将接收两个参数,这两个参数分别表示问题数量和时间限制。

接着,将全局变量timeLeft的值设置为参数SelectedTimeLimit的值,将全局变量totalQuestionsToAsk的值设置为参数numberOfQuestions的值。在后面的代码中你将会看到,这两个全局变量将用以判断问题是否已经回答完毕,以及检查时间限制是否已经到点。

在resetQuiz()函数的最后,添加了一个计时器,以监测剩余的时间。一种情况是计时器已经到点,剩余时间已经用完,即变量timeLeft的值为–1。如果变量timeLeft的值为–1时,则使用window对象的status属性,在浏览器的状态栏中显示一条时间到点的信息。注意,在Netscape浏览器中,当框架页改变时,将在浏览器的状态栏中显示Document:Done以覆盖No Time Limit信息。如果变量timeLeft的值不是–1,则使用setInterval()方法启动一个计时器,以每隔1s调用一次updateTimeLeft()函数。

updateTimeLeft()函数是一个新添加的函数。下面的代码用以创建updateTimeLeft()函数。将该代码添加在脚本块其他函数的下面。

function updateTimeLeft()

{

timeLeft--;

if (timeLeft == 0)

{

alert("Time’s Up");

numberOfQuestionsAsked = totalQuestionsToAsk;

window.top.fraQuizPage.location.href = "AskQuestion.htm";

}

else

{

var minutes = Math.floor(timeLeft / 60);

var seconds = timeLeft - (60 * minutes);

if (minutes < 10)

minutes = "0" + minutes;

if (seconds < 10)

seconds = "0" + seconds;

window.status = "Time left is " + minutes + ":" + seconds;

}

}

updateTimeLeft()函数完成了3个功能。首先,它将剩余时间减1,即timeLeft--;然后判断是否还有剩余的时间,当剩余时间为0时,则停止小测试程序;否则,在浏览器的状态栏中显示剩余的时间,以便提示用户。

前面我们已经知道,当调用resetQuiz()函数时,将复位在线小测试程序,并将全局变量timeLeft设置为以秒为单位的时限值,在规定的时间内用户必须完成小测试。每隔1s将调用一次updateTimeLeft()函数,在updateTimeLeft()函数的第一行代码中,将剩余的时间减去1s:

 timeLeft--;

其后的if语句用以检查timeLeft是否为0,即是否还有剩余时间。如果timeLeft为0,则表示无剩余时间,这时将变量numberOfQuestionsAsked的值设置为全局变量totalQuestionsToAsk的值,即用户所选择的要回答问题的数量。接着,将页面导航到AskQuestion.htm页面,在该页面中将认为问题已经回答完毕并终止小测试程序,而不是继续提出一个新问题。

如果还有剩余时间,则该if语句的else子句将被执行,并更新浏览器的状态栏,以显示剩余的分钟数和秒数。

这里,需要将timeLeft中保存的以秒为单位的时间值拆分成分钟数和秒数。首先,可以使用下面这行代码获取分钟数的值:

var minutes = Math.floor(timeLeft / 60);

上面的代码将返回变量timeLeft中保存的总秒数除以60的商的整数部分,这正是我们所需要的分钟数。而下面的代码则用以获得秒数:

var seconds = timeLeft - (60 * minutes);

在上面的代码中,用总的秒数timeLeft减去分钟数所对应的秒数,即可得到除去分钟数之后剩余的秒数。例如,如果timeLeft是61,则分钟数为:

minutes = 61 / 60 = 1.01667

取整后将返回整数1,表示1分钟,而剩余的秒数为:

seconds = 61 - (60 * 1) = 1

我们希望按“分钟:秒钟”的格式将剩余时间显示在浏览器的状态栏中,例如对于上面的例子,希望将剩余时间显示为01:01。但是,当分钟或者秒钟的值小于10时,把分钟和秒钟的字符串连接起来将是1:1这样一个字符串。对于在线小测试程序,分钟数不会超过5,实际上只需直接在前面加上0即可。但是,为了使代码能适应未来需求发生的变化—— 例如允许用户回答问题的时间超过9分钟,则应使用if语句进行检查,以便确定分钟数是否小于10。

要修正格式问题,只需在分钟数或秒钟数小于10时,在其前面添加一个额外的0即可,相应代码如下所示:

if (minutes < 10)

minutes = "0" + minutes;

if (seconds < 10)

seconds = "0" + seconds;

最后,更新浏览器状态栏中剩余时间的显示:

window.status = "Time left is " + minutes + ":" + seconds;

在前面的这两个函数中,我们用到了几个新的全局变量。这些全局变量为:

var timeLeft =-1;

var totalQuestionsToAsk = 0;

var quizTimerId = 0;

请将上面全局变量的定义添加到脚本块的开始处。

最后,再对getQuestion()函数进行两处较小的修改,就能完成本章中小测试程序的修改。

首先,修改的是函数开始处的if语句:

if (totalQuestionsToAsk != numberOfQuestionsAsked)

{

var questionNumber = Math.floor(Math.random() * questions.length);

在上一版本的在线小测试程序中,只要可用的问题还没有问完,就可以继续提问。现在,当变量totalQuestionsToAsk的值不等于实际所问问题的数量时,则继续进行提问。totalQuestionsToAsk是一个全局变量,其中保存的是用户在下拉列表框中选中的问题的数量。在前面的代码中,用户选中的问题数量将作为参数传递给resetQuiz()函数,并在resetQuiz()函数中赋值给全局变量totalQuestionsToAsk。

第二个修改的地方是else子句。当小测试结束时,将把用户小测试结果的汇总信息输出到页面上。注意,在前面的resetQuiz()函数中,我们设置了一个计时器以监测剩余时间,当时间到点时就结束在线小测试程序。现在,当小测试程序结束时,应该使用clearInterval()方法清除该计时器。当计时器启动时,该计时器的ID号已经保存在全局变量quizTimerId中,只需将该计时器的ID号传递给clearInterval()方法,即可清除该计时器。另外,当用户并未设置答题的时限时,即用户未在cboTimeLimit下拉列表框中选择一个时限时,则timeLeft的值将为–1,这时,前面的resetQuiz()函数中并未设置任何计时器,因此,这里也就无须对计时器进行清除。为此,在下面的代码中,使用了if (timeLeft != –1)进行判断:

currentQNumber = questionNumber;

questionsAsked[questionNumber] = true;

}

else

{

if (timeLeft != -1)

{

clearInterval(quizTimerId);

}

questionHTML = "<h3>Quiz Complete</h3>";

questionHTML = questionHTML + "You got" + numberOfQuestionsCorrect;

到此为止,所有的修改都已经完成了。将上面修改后的代码保存为GlobalFunctions.htm文件。并在浏览器中加载TriviaQuiz.htm页面,以启动在线小测试程序。

如果修改后的代码正常,我们将看到一个如图9-8所示的页面。

图  9-8

如果在Time Limit下拉列表框中选择了一个时限,并单击Start Quiz按钮,则第一个随机抽取的问题将显示在页面上,并且计时器将开始倒计时,在浏览器的状态栏中将显示剩余的时间。

在Firefox浏览器和IE 7版本的浏览器中,通过JavaScript修改浏览器状态栏的功能在默认情况下是被禁止的。要在Firefox浏览器中打开该功能,只需选择Tools | Options,然后选择Content标签页。然后,单击Advanced Options按钮,然后选中Change Status Bar Text复选框。对于IE 7浏览器,只需选择Tools | Internet Options,然后再选择Security标签页。单击Internet,然后单击custom level,在打开的窗口中将滚动条下拉到Allow status bar updates via script复选框,并选中该复选框。

本章中对“在线小测试”程序的修改就到这里。在第11章中,我们将再次回到“在线小测试”程序,以介绍如何使用cookie将信息保存在用户的计算机上,以便提供一个前面所答题目信息的表格。