JS教程:线小测试程序


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将信息保存在用户的计算机上,以便提供一个前面所答题目信息的表格。



相关阅读:
User Tips: Using Return Values from a SQL Server Stored Procedure to Customize Error Messages_QQGB.c
php设计模式介绍之编程惯用法
Jquery 动态添加按钮实现代码
javascript循环数组的方法
JavaScript判断浏览器类型及版本
ASP.NET 页面刷新的实现方法(包括html,js)
私有属性和使用JavaScript的信息隐藏
ubuntu英文环境下使用小企鹅
jQuery 使用手册(三)
win7中如何设计文件的打开方式
SQLSERVER2005 中树形数据的递归查询
使用php通过socket进行发信源码,支持发信认证
关于DOCTYPE的一些了解
php 生成饼图 三维饼图
快速导航

Copyright © 2016 phpStudy | 皖ICP备18014864号-4