目錄javascript
以前在項目中寫了定時器來作循環播放,可是老是會有越走越快的問題,開始是覺得先後的HTML代碼拼接的有問題,時間緊急的狀況下反覆改了不少也沒什麼效果,後來發現是js定時器的問題,在這裏記錄一下。html
使用js定時器(setinterval)首要的問題就是要記得清除,即調用(clearInterval)方法,因爲沒有使用定時器的經驗,我一開始是沒有清除定時器,程序每一次初始化的時候都調用一次定時器,以前的定時器實例沒有被銷燬,新的定時器又開始執行,就會出現1s變0.5s,0.5s變0.25秒的狀況,從觀感上來看就是定時器「越走越快」了。java
這個過程能夠用幾行簡單的代碼模擬一下code
<label id="lblShowNum"></label> <input type="button" id="btnStart" value="啓動" /> <input type="button" id="btnClear" value="清除" />
window.onload = function () { var i = 0; var timer; document.getElementById("btnStart").onclick = function () { timer = setInterval( function () { i++; document.getElementById("lblShowNum").innerText = i; }, 1000); } document.getElementById("btnClear").onclick = function () { clearInterval(timer); } }
若是隻點擊一次「啓動」按鈕,定時器會正常運行,點擊「清除」按鈕就能夠暫停定時器,可是每一次點擊「啓動」按鈕,都會提升數字的增速,而清除功能也再也不起做用,這就是由於在每一次點擊「啓動」的時候都有新的定時器被建立。htm
但爲何清除的方法會失效呢?在代碼中咱們定義了一個變量timer去接收定時器,對timer操做是否是就能清除定時器了呢?並非是這樣,首先看下setinterval()返回值的說明對象
一個能夠傳遞給 Window.clearInterval() 從而取消對 code 的週期性執行的值。ip
這裏能夠看出這個返回值並非定時器自己,它只是一個用於傳遞的返回值,若是想固然的把它當作定時器,覺得每次初始化賦值就是新的定時器就錯了,我最開始就是這樣想的。get
每一次給timer賦值都是在建立新的定時器對象,並且以前的定時器也並無被清除,因此這時候調用clearInterval(timer)清除的只是最後一個被建立的定時器對象罷了。input
使用上面的例子就能夠簡單的用肉眼觀察效果,先點擊一次啓動觀察速度,再點擊第二次,會看到速度有明顯的提高,這時候使用清除功能,速度就會回到第一次啓動的狀態,可是屢次點擊清除是沒有用的,若是想看準確的結果能夠將時間打印出來進行比較。it
看到這裏,答案呼之欲出了,很簡單,在每次初始化定時器以前先執行清除操做,保證以前的定時器被清除了就不會發生越走越快的狀況,因此其實並非定時器越走越快,而是有多個定時器在執行,定時器裏面的程序執行的頻率提升了。
window.onload = function () { var i = 0; var timer; document.getElementById("btnStart").onclick = function () { clearInterval(timer); timer = setInterval( function () { i++; document.getElementById("lblShowNum").innerText = i; }, 1000); } document.getElementById("btnClear").onclick = function () { clearInterval(timer); } }