首页 > 开发 > JS > 正文

JS教程:线小测试程序

2024-09-06 12:40:55
字体:
来源:转载
供稿:网友

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表