周劍強(qiáng)
(忻州職業(yè)技術(shù)學(xué)院,山西忻州 034000)
在動(dòng)態(tài)網(wǎng)頁(yè)中,我們經(jīng)常會(huì)看到自動(dòng)切換圖片的幻燈片效果和滾動(dòng)文字效果。這些效果都需要頁(yè)面定時(shí)自動(dòng)完成一些操作,這時(shí)候就用到了JavaScript中的計(jì)時(shí)器技術(shù)。
在瀏覽器對(duì)象模型(BOM)中,Window對(duì)象有一種方法可以實(shí)現(xiàn)計(jì)時(shí)功能,就是setInterval(),它的語(yǔ)法如下:
setInterval(code,millisec);
其中,第一個(gè)參數(shù)code是要執(zhí)行的代碼字符串,第二個(gè)參數(shù)millisec是以毫秒為單位的延遲時(shí)間。實(shí)現(xiàn)的功能是延遲millisec毫秒后執(zhí)行code代碼,并且以millisec為周期,不停地重復(fù)執(zhí)行code代碼。
下面的實(shí)例中,我們使用setInterval()方法讓網(wǎng)頁(yè)中的圖像定時(shí)自動(dòng)切換,代碼如下:
在本例中有三個(gè)圖片,分別是img1.jpg、img2.jpg、img3.jpg,網(wǎng)頁(yè)上只有一個(gè)<img>標(biāo)簽。先定義了一個(gè)函數(shù)img_change(),它的功能是讓<img>標(biāo)簽的圖像源在三個(gè)圖片之間切換。然后給<body>標(biāo)簽設(shè)定了一個(gè)onload事件,通過onload事件來觸發(fā)setInterval()方法,實(shí)現(xiàn)的效果是每隔2000毫秒執(zhí)行一次img_change()函數(shù),也就是每隔2秒種切換一次圖片。
除了setInterval()方法,Window對(duì)象的 setTimeout()方法也可以實(shí)現(xiàn)計(jì)時(shí)功能。它的語(yǔ)法如下:
setTimeout(code,millisec);
其中兩個(gè)參數(shù)的含義和setInterval()方法一樣,實(shí)現(xiàn)的功能也是延遲millisec毫秒后執(zhí)行code代碼。不同的是,它只執(zhí)行一次code代碼,不作周期性的重復(fù)。所以,要想用setTimeout()方法定期重復(fù)執(zhí)行code代碼,就需使用遞歸函數(shù),也就是要在執(zhí)行的代碼中再調(diào)用自己。
下面我們使用setTimeout()方法來實(shí)現(xiàn)例1中的效果,代碼如下:
本例中,把setTimeout()方法寫在了img_change()函數(shù)內(nèi)部,而setTimeout()本身又調(diào)用了img_change()函數(shù)作為第一個(gè)參數(shù),通過這種方法實(shí)現(xiàn)了對(duì)img_change()函數(shù)的循環(huán)調(diào)用。
當(dāng)setTimeout()方法被設(shè)定為定期循環(huán)執(zhí)行后,可以使用if...else語(yǔ)法設(shè)定一個(gè)條件讓它停止執(zhí)行,也可以使用window對(duì)象的另一個(gè)方法讓它停止,就是clearTimeout()方法,使用方法如下:
myID=setTimeout(code,millisec);
clearTimeout(myID);
使用setTimeout()方法時(shí)會(huì)返回一個(gè)值,該值是一個(gè)整數(shù),它是唯一標(biāo)識(shí)該計(jì)時(shí)器的ID號(hào)。使用clearTimeout()方法,以計(jì)時(shí)器的ID號(hào)為參數(shù),就可以停止該計(jì)時(shí)器。對(duì)于使用setInterval()方法的計(jì)時(shí)器,clearInterval()方法也可以讓它停止,其語(yǔ)法與clearTimeout()方法完全相同。下面的實(shí)例中,我們使用setTimeout()和clearTimeout()來起動(dòng)和停止計(jì)時(shí),代碼如下:
本例中,先定義兩個(gè)函數(shù)countstart()和countstop(),其功能分別是開始計(jì)時(shí)和停止計(jì)時(shí)。頁(yè)面中的單行文本框用于顯示累計(jì)的時(shí)間,以秒為單位。另外兩個(gè)按鈕,分別用來觸發(fā)countstart()函數(shù)和countstop()函數(shù)。頁(yè)面加載后,單擊第一個(gè)按鈕開始計(jì)時(shí),文本框中的數(shù)字每秒加1,單擊第二個(gè)按鈕時(shí)計(jì)時(shí)停止。需要注意的是,當(dāng)我們多次單擊第一個(gè)按鈕時(shí),會(huì)發(fā)現(xiàn)文本框中數(shù)字的變化會(huì)加快,而且此時(shí)要想停止計(jì)時(shí),需多次單擊第二個(gè)按鈕。之所以會(huì)出現(xiàn)這種現(xiàn)象,是因?yàn)槊繂螕粢淮伍_始計(jì)時(shí)按鈕就會(huì)啟動(dòng)一個(gè)countstart()函數(shù),而每一個(gè)countstart()函數(shù)都會(huì)導(dǎo)致文本框中數(shù)字的變化。如果把這樣的計(jì)時(shí)器應(yīng)用到網(wǎng)頁(yè)中,當(dāng)用戶不小心多次點(diǎn)到開始計(jì)時(shí)按鈕,就會(huì)導(dǎo)致計(jì)時(shí)器失靈。為了解決這個(gè)問題,需要在程序中引入一個(gè)變量作為標(biāo)記,用它來記錄計(jì)時(shí)是否已開始,如果計(jì)時(shí)已開始,開始計(jì)時(shí)按鈕將不再可用,從而避免了用戶的誤操作。依據(jù)這種原理,我們對(duì)例3中的JavaScript代碼作如下更改:
本例中總共定義了三個(gè)函數(shù),變量mark用來記錄計(jì)時(shí)是否已開始。在第一個(gè)函數(shù)中,當(dāng)計(jì)時(shí)開始時(shí)給mark賦值為1。而在第三個(gè)函數(shù)中,使用if語(yǔ)句進(jìn)行判斷,只有mark的值為0時(shí)才可以開始計(jì)時(shí)。這樣就避免了對(duì)計(jì)時(shí)器的重復(fù)啟動(dòng)。
setTimeout()方法和setInterval()方法都可以用于計(jì)時(shí),但實(shí)現(xiàn)的最終效果有所不同。setTimeout(code,millisec)這句代碼是要在millisec毫秒的延時(shí)后執(zhí)行code,如果執(zhí)行code本身需要200毫秒的時(shí)間,那么計(jì)時(shí)器的實(shí)際循環(huán)周期為millisec+200;setInterval(code,millisec)這句代碼嚴(yán)格以millisec為周期重復(fù)執(zhí)行code,如果執(zhí)行code代碼需要200毫秒的時(shí)間,那么執(zhí)行之前的延時(shí)為millisec-200,計(jì)時(shí)器的循環(huán)周期還是millisec。如果code代碼的執(zhí)行時(shí)間超過了millisec,計(jì)時(shí)器會(huì)忽略本次執(zhí)行,等到下一個(gè)周期開始再執(zhí)行。
通過上述研究我們看到,setTimeout()方法和setInterval()方法都可以實(shí)現(xiàn)計(jì)時(shí)功能,使用方法稍有不同,setTimeout()方法需要在參數(shù)中調(diào)用自身才能實(shí)現(xiàn)不斷的循環(huán)。兩種方法實(shí)現(xiàn)的計(jì)時(shí)器效果也有差別,我們要從計(jì)時(shí)器的功用出發(fā),根據(jù)實(shí)際需求進(jìn)行選擇。setInterval()方法嚴(yán)格按照既定周期執(zhí)行,所以如果要精確計(jì)時(shí),最好使用該方法;而setTimeout()方法保證了兩次執(zhí)行之間的延時(shí)保持不變,所以如果計(jì)時(shí)器調(diào)用的函數(shù)比較復(fù)雜,執(zhí)行時(shí)間較長(zhǎng),而又不想在頻繁調(diào)用時(shí)引起混亂,最好使用setTimeout()方法。
[1]Stephen Chapman.JavaScript By Example-setTimeout[EB/OL].http://javascript.about.com/od/byexample/a/function-settimeout-example.htm,2011.
[2]Jeremy Keith.JavaScript DOM 編程藝術(shù)[M].北京:人民郵電出版社,2007.
[3]Nicholas C.Zakas.JavaScript高級(jí)程序設(shè)計(jì)[M].北京:人民郵電出版社,2006.
[4]Flanagan.Javascript權(quán)威指南[M].北京:機(jī)械工業(yè)出版社,2007.
[5]張大富,黃中敏.JavaScript動(dòng)態(tài)網(wǎng)頁(yè)編程實(shí)例手冊(cè)[M].北京:海洋出版社,2005.