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