摘要:大多數瀏覽器并沒有精確到毫秒級別的觸發事件,例如,我們設定某個函數在毫秒后執行,在老版本的中,這個函數至少會在毫秒以后執行。三實戰光說不練假把式,現在我們就用上面介紹的三種定時器完成進度條的效果。
一.常見定時器
我們常見的定時器有以下兩種 1. window.setTimeout 用于在指定的毫秒數后執行某段既定的代碼 2. window.setInterval 用于每隔一段毫秒數重復執行既定的代碼 這兩個方法都可以通過手工設置時間來設定是多少毫秒后執行這段代碼,或者是每隔多少毫秒執行這段代碼。
雖然我們期待瀏覽器按照我們設定的時間精確的執行代碼,但是js卻不能保證代碼能恰好在那個時間點被運行,原因有兩個。
大多數瀏覽器并沒有精確到毫秒級別的觸發事件,例如,我們設定某個函數在3毫秒后執行,在老版本的IE中,這個函數至少會在15毫秒以后執行。而在現代瀏覽器中,這個數值會短一點,但時間差一般也會超過1毫秒。
第二個原因與js的運行機制有關,具體見JavaScript 運行機制詳解:再談Event Loop.簡單來說,就是js是一個單線程的解釋器,一段時間只能執行一段代碼,所以運行時分為主線程和任務隊列兩部分。而我們在定時器中設置的時間,僅代表1000毫秒后把這個任務插入到任務隊列中,而此時必須要等到主線程的代碼執行完畢,才能執行任務隊列中的定時器的任務(在任務隊列中也有調度,不一定第一個執行當前任務),因此時間是無法保證的。
二、requestAnimationFrame那有沒有時間準確的定時器呢?有一種選擇是requestAnimationFrame. 示例如下:
function animateMe(){ requestAnimationFrame(function(){ console.log(new Date()); animateMe(); }) } animateMe();
這個api的原理是在由系統來決定回調函數的執行時機,在每一次系統繪制之前,會主動調用requestAnimationFrame中的回調函數,而頻率也緊緊跟隨瀏覽器的刷新頻率。比如一般電腦的刷新頻率通常為60Hz,即一秒鐘重繪60次,那么回調函數就等于1000/60=16.7毫秒被執行一次,而如果刷新頻率變為75Hz,那么這個時間就變為1000/75=13.3毫秒被執行一次。這樣能保證回調函數在每一次繪制的間隔時間內只被執行一次,因此它的時間是可靠的。
三、實戰光說不練假把式,現在我們就用上面介紹的三種定時器完成進度條的效果。
1.setInterval
var timer; $(".runBtn").click(function(){ clearInterval(timer); $("#bar").width(0); timer = setInterval(function(){ if($("#bar").width() < 500){ $("#bar").width($("#bar").width()+5); $("#bar").text($("#bar").width()/5+"%"); }else{ clearInterval(timer); } },16); });
點此預覽效果
2.setTimeout
var timer; $(".runBtn").click(function(){ clearTimeout(timer); $("#bar").width(0); timer = setTimeout(function fn(){ if($("#bar").width() < 500){ $("#bar").width($("#bar").width()+5); $("#bar").text($("#bar").width()/5+"%"); timer = setTimeout(fn,16); }else{ clearTimeout(timer); } },16); });
點此預覽效果
3.requestAnimationFrame
var timer; $(".runBtn").click(function(){ cancelAnimationFrame(timer); $("#bar").width(0); timer = requestAnimationFrame(function fn(){ if($("#bar").width() < 500){ $("#bar").width($("#bar").width()+5); $("#bar").text($("#bar").width()/5+"%"); requestAnimationFrame(fn); }else{ cancelAnimationFrame(timer); } }); });
點此預覽效果
四、最后文章都來自本人的總結,難免有些紕漏,歡迎大家指正。一起學習,一起進步。如果覺得不錯,歡迎點贊收藏嚶嚶嚶~~~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107692.html
摘要:定時器方法相關方法有四種。返回值返回值是一個正整數,表示定時器的編號。這個值可以傳遞給來取消該定時器。使用方法很簡單只有一個參數,該參數為您要取消定時器的標識符。用法很簡單當代碼運行到這行的時候,會取消所設置的定時器。 簡單介紹在JavaScript中定時器有兩個 setInterval() 與 setTime...
摘要:當間隔時間設置較小時,將會導致回調函數堆積。處理可能阻塞的代碼最簡單且最可控的方式就是在回調函數內部使用函數。但是很明顯,由于指定最大值的限制,還會有定時器沒有被清除掉。另外,盡量避免使用函數,從而避免可能導致的回調函數堆積現象。 由于 Javascript 是異步的,因此我們可以通過 setTimeout 和 setInterval 函數來指定特定時間執行代碼。 function ...
摘要:說到中的定時器,我們肯定會想到和這兩個函數。第一個回調一執行,又開啟了第二個,這個定時器也是期望延時之后能夠執行它的回調函數。可以用下面的圖來概括總結上面對定時器執行原理進行了簡要的分析,希望能夠幫助我們更深入的理解。 說到 javascript 中的定時器,我們肯定會想到 setTimeout() 和 setInterval() 這兩個函數。本文將從 事件循環(Event Loop)...
摘要:提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。所以,這個新標準并沒有改變單線程的本質。事件循環主線程線程只會做一件事,就是從消息隊列里面取消息執行消息,再取消息再執行。工作線程是生產者,主線程是消費者。 最近項目中遇到了一個場景,其實很常見,就是定時獲取接口刷新數據。那么問題來了,假設我設置的定時時間為1s,而數據接口返回大于1s,應該用同步阻塞還是異步?我們...
閱讀 1444·2023-04-25 16:31
閱讀 2046·2021-11-24 10:33
閱讀 2751·2021-09-23 11:33
閱讀 2537·2021-09-23 11:31
閱讀 2915·2021-09-08 09:45
閱讀 2345·2021-09-06 15:02
閱讀 2652·2019-08-30 14:21
閱讀 2321·2019-08-30 12:56