setInterval()和setTimeout()方法都是js原生的定時方法,當然它們兩個的作用也是不同的,並且最近在做上下滾動公告欄的時候,發現了setInterval()非常令人抓狂的問題,那就是用setInterval()做的定時滾動會隨著瀏覽器頁面切換變得無法控制!為什麼會說無法控制呢,因 ...
setInterval()和setTimeout()方法都是js原生的定時方法,當然它們兩個的作用也是不同的,並且最近在做上下滾動公告欄的時候,發現了setInterval()非常令人抓狂的問題,那就是用setInterval()做的定時滾動會隨著瀏覽器頁面切換變得無法控制!為什麼會說無法控制呢,因為在切換頁面一段時間之後,我本設置3秒滾動一次變成了一秒一次,滾動變得越來越快了。對於這個問題我花了一個上午得時間去解決。下麵我們先瞭解一下setInterval()和setTimeout()方法的區別
setInterval()和setTimeout()方法的區別
setInterval()可按照指定的周期(以毫秒計)來調用函數或計算表達式,直到直到clearInterval()方法 被調用或視窗被關閉。。簡單的說就是每幾秒執行一次,無限執行。
而它的用法也非常簡單。
setInterval(function(){ alert("Hello"); }, 3000);
這句代碼的意思是每3秒彈出一個“Hello”對話框。(每3秒彈出一次,無限彈出)
setTimeout() 方法用於在指定的毫秒數後調用函數或計算表達式。簡單得說就是幾秒之後,你把我交給你得任務執行了。(執行一次)
setTimeout(function(){ alert("Hello"); }, 3000);
這句代碼的意思是3秒之後彈出一個“Hello”對話框。(只彈出一次)
瞭解完setInterval()和setTimeout()的區別後,如果你想做一個一直滾動的公告欄,肯定會選擇setInterval()方法吧,當然我也是這樣選的,剛開始感覺還不錯,直到我發現了前面所說的那個setInterval越來越快的問題.......
setInterval()的弊端越來越快的問題
經過仔細排查之後,我排除了我自己代碼的問題,於是就開始查各種資料。最後才曉得這是setInterval()自身的問題。下麵引用大佬的一段話來解釋為什麼使用setInterval會出現越來越快的問題。
“JavaScript是運行在單線程的環境中的,所以這就意味著定時器就成了要執行的計劃!而不是必須要執行的鐵律! 為啥呢? 當函數開始執行時在棧中創建出來一個棧幀,這個棧幀的執行是需要時間的,假設有3秒,在這三秒內,JavaScript的單線程特點就會確保在這3秒內全力的專一的去解決掉這個棧幀(函數)。所以在這個函數運行的時候定時器是沒有能力終止他的運行的,因此當函數的運行時間大於間隔時間時,間隔時間1秒到了,但是程式還有2秒沒有執行完,那你也給我老老實實的等著函數執行完!!!”
知道了問題的原因,那我們再來看一下怎麼去解決這個問題。
使用setTimeout迴圈來解決setInterval越來越快的問題
代碼很簡單,直接上代碼
var i=0; function show() { console.log(i); i++; if(i<5){ setTimeout(show,1000); } } show();
上面也就是做了一個setTimeout迴圈,讓setTimeout也可以達到setInterval()無限迴圈的效果,但是不會出現setInterval()越來越快的問題。