在本章中,我們將對“在線小測試”程序作兩處修改。一是允許用戶首先選擇回答完問題所需要的時間,二是允許用戶選擇要回答多少個問題。
要把“在線小測試”程序轉換為一個基于計時器的程序,只需修改兩個頁面,即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頁面?,F在,我們需要獲取用戶在下拉列表框中選中的問題數量和時間限制。后面我們還將看到,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()函數并不接收參數?,F在,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);
在上一版本的在線小測試程序中,只要可用的問題還沒有問完,就可以繼續提問?,F在,當變量totalquestionstoask的值不等于實際所問問題的數量時,則繼續進行提問。totalquestionstoask是一個全局變量,其中保存的是用戶在下拉列表框中選中的問題的數量。在前面的代碼中,用戶選中的問題數量將作為參數傳遞給resetquiz()函數,并在resetquiz()函數中賦值給全局變量totalquestionstoask。
第二個修改的地方是else子句。當小測試結束時,將把用戶小測試結果的匯總信息輸出到頁面上。注意,在前面的resetquiz()函數中,我們設置了一個計時器以監測剩余時間,當時間到點時就結束在線小測試程序?,F在,當小測試程序結束時,應該使用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將信息保存在用戶的計算機上,以便提供一個前面所答題目信息的表格。
新聞熱點
疑難解答