今天在寫個圖片切換的問題 有動畫滯后的問題,才動手去查setTimeout 和clearTimeout。之前寫的圖片播放器也有類似的問題,有自動start按鈕 和stop按鈕,
其他都正常,問題出在每次多次快速的點擊start按鈕時,圖片播放的速度會變塊很多,而且沒有規律。當時也沒有去想這個問題,直到今天遇到了類似的問題
才決定去一探究竟。
列舉個簡單累加例子:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>計時器</title>
</head>
<script type="text/javascript">var num=0;var i;function startCount(){document.getElementById('count').value=num;num=num+1;i=setTimeout("startCount()",1000);}function stopCount(){clearTimeout(i);}
</script>
</head>
<body><form><input type="text" id="count" /><input type="button" value="Start" οnclick="startCount() "/><input type="button" value="Stop" οnclick="stopCount()" /></form>
</body>
</html>
效果如下:
? ?點擊開始累加。多次點擊開始按鈕時,數字飆升的很快,取決于你點擊的速度。
function startCount(){ clearTimeout(i);document.getElementById('count').value=num;num=num+1;i=setTimeout("startCount()",1000);}
后來給startCount函數添加個clearTimeout(i);就解決了問題,當時不知其所以然。
今天仔細想了下原來是這么回事。
為什么在沒有設置clearTimeout的時候多次點擊數字會飆升?
1:當我們點擊start按鈕后就開始運行函數,先顯示數字0,然后就運行到setTimeout,1s后執行一次startCount函數,因為函數內部有setTimeout ?所以函數會一直執行下去,
?而當我們再次點擊start按鈕時,這個函數還會再執行一次,之前這個函數已經在執行了。那么這個函數就是交替執行,那么數字就會混亂,累加的速度翻倍了,至于和點擊的次數是什么關系,沒有過深入的研究,就不得而知了。
2:為什么在我們設置了clearTimeout后就可以避免這種情況的出現?
我們來運行一次函數,點擊開始,函數開始運行,當運行到setTtimeout的時候設置了該函數1s后再運行一次,此時有個返回值 i 。在這個指令下達后,我們假設在這個1s的時間內再次點擊start按鈕會發生什么?(1s的時間還是很久的,我們可以點擊N次鼠標),把這個被setTimeout設置執行的函數編號為A,我們再次點擊觸發執行的函數編號為B;那么B是瞬發的(計算機的速度毋庸置疑),而這個A還得0~1s之后才去執行(B在A先執行),b執行的時候函數內部有clearTimeout,所以就把這個setTimeout設置的A取消了,不用執行了。那么就只有B在執行了,無論怎么點擊都不會出現混亂的情況了。
? ? 那么問題來了,你設置了clearTimeout 那不就把設置的setTimeout終止掉了嗎?那不就不會累加了嗎?
? 說真的當時我也疑惑了,那么來分析分析。函數執行一次,setTimeout設置了1s后再執行函數一次,(沒有setTimeout就不運行函數了),指令下達后執行,我們去執行,
當進入到函數內部(也就是函數體)的時候遇到了clearTimeout 他說你們別再執行函數了。可我們已經在執行了,況且我們的指令也就是執行這一次,我們執行完了就不會執行了。此時的clearTimeout對我們這次執行函數沒什么影響。(因為我們本來就是只執行這一次,就沒有下次別執行的說法),如果把clearTimeout放在函數體外面就不一樣了,我可以在外面先把你攔截,在你還沒有執行,還沒有進入函數內部的時候就攔截你,這樣就達到了停止的作用,類似top按鈕。
? ?END。我自己也算是理解了。
?
? 自己的一些理解,如有不當之出,還望路過的園友不吝指教,助我早日走上正道。
?