這是一個單純的javascript的實作,牽涉到setInterval的用法和javascript的物件寫法。
我希望可以將整個倒數計時寫成一個物件,透過建構物件之後就可以開始進行倒數,而不用還要處理其它事情。所以所有的事情通通要包在物件裡面,包括setInterval。所以我這麼寫:
function countdown(){
this.count=function(){
//執行倒數計時的動作
….
}
setInterval(‘this.count()’,1000); //設定每秒執行一次倒數
}
new countdown();
結果遇到的第一個問題就是,在setInterval裡的this沒有count這個函數。接下來的說明必須具備物件導向的概念才能理解。
物件有屬性及方法,物件的屬性可以再為物件,姑且用父物件及子物件來稱呼。若要操作父物件裡的子物件的屬性,必須使用「父物件.子物件.子物件屬性」這樣子的語法,上述狀況的原因是因為用「父物件.子物件屬性」來操作,所以會找不到屬性,就算剛好有同名屬性,也不是子物件的屬性。
後來苦思了半天,原來在setInterval的執行下,其中的this指向window(因為setInterval是window的屬性),而 window顯然在預設的狀況下並沒有count,即便當時window有count這個函數,也並非是新建物件裡的count。所以我必須要讓setInterval識得新建立的物件,於是乎在建立物件的時候就要把物件的名字也一併當作起始參數給放進去:
var dd=new countdown(‘dd’);
function countdown(_self){
this.count=function(){
//執行倒數計時的動作
….
}
setInterval(_self+‘.count()’,1000); //設定每秒執行一次倒數
}
到這裡的確可以倒數了。不過問題又來了,如果我想中止倒數該怎麼辦?每一個setInterval都會回傳一個值(編號),我們可以透過這個回傳值再搭配clearInterval來中止該次的setInterval。所以我只要記下它的值,接著再透過clearInterval來中斷倒數就可以了。於是乎程式碼變成這樣:
var dd=new countdown(‘dd’);
function countdown(_self){
this.sid;
this.count=function(){
//執行倒數計時的動作
….
}
this.stop=function(){
clearInterval(this.sid);
}
this.sid=setInterval(_self+’.count()’,1000); //設定每秒執行一次倒數
}
我就可以透過已經建立的物件dd,再加上stop來停止倒數,例如dd.stop()。但是停止之後要再啟動怎麼辦?不是再產生一個新的物件吧?太浪費了。讓dd再開始倒數就好,而且本來在物件就有一個倒數的動作,只要重新執行它一次就好。所以再改寫一次程式碼:
var dd=new countdown(‘dd’);
function countdown(_self){
this.sid;
this.count=function(){
//執行倒數計時的動作
….
}
this.stop=function(){
clearInterval(this.sid);
}
this.start=function(){
this.sid=setInterval(_self+’.count()’,1000); //設定每秒執行一次倒數
}
this.start(); //建立物件後會啟動它
}
在中斷倒數之後,若要再啟動倒數,我們可以利用已經建好的物件dd,再加上它的start來重新啟動,例如:dd.start()。中斷及再次啟動的函數,像是dd.stop()和dd.start()只要設給dom物件的click事件觸發執行即可以了。