在之前的文章【javascript中的定時器】中,簡單的介紹了一下setTimeout()和setInterval()兩個定時器方法的使用和原理。不過在昨天給個人node即時聊天系統添加消息提示時,發現了定時器新的特性。固然,這對於我來講是新的發現,其實這些東西早就已經存在了。html
在setTimeout()和setInterval()咱們可以設定時間間隔,來讓下個事件大體
發生在哪一個時間段。假如咱們設置時間間隔是0的話,那是否是就會在0ms以後執行呢,也就是當即執行。咱們能夠採用下面的代碼輸出一下:java
function get(){ var timer = null; var date = null; var diff = 0; var last = 0; var now = 0; var nums = 0; var color = '#000'; var process = document.getElementById("process"); timer = setInterval(function(){ date = new Date(); now = date.getTime(); diff = now-last; // 先後兩個時間差 last = now; nums++; color = diff===0?'#f00':'#000'; process.innerHTML += '<p>'+now+' (<span style="color:'+color+'">'+diff+'</span>)</p>'; if(nums>=100){ clearInterval(timer); } }, 0); } get();
咱們把每次執行setInterval()先後的時間差打印到屏幕中(如下數據使用chrome 42.0.2311.90版本測試):node
1429545782409 (1) 1429545782412 (3) 1429545782414 (2) 1429545782420 (6) 1429545782425 (5) 1429545782430 (5) 1429545782437 (7) 1429545782443 (6) 1429545782449 (6) 1429545782454 (5) 1429545782460 (6) 1429545782466 (6) 1429545782471 (5) 1429545782476 (5) ...
從打印出的數據能夠看出,setInterval()的時間間隔爲0ms時,輸出的時間差基本都在1~10ms之間,也是能在能夠接受的範圍內。IE11下的測試與chrome的數據基本一致,而在firefox下可以出現0
的時間差。web
其實無論是把時間間隔設定爲0ms仍是其餘的時間間隔,運行時都會有時間偏差的,比設定的間隔多1~16ms毫秒左右,有的時候還會相差更多。chrome
咱們有時會在某個場合對標題進行閃動,提示給用戶當前標籤頁有新消息產生:瀏覽器
var backup = document.title; // 存儲原標題 function blink(){ document.title = document.title == backup? "【有新消息】" : backup; } blink(); timer = setInterval(blink, 500);
上面的代碼可以進行500ms的標題輪流閃動,當咱們處在當前標籤頁時,基本感受不出定時器產生的偏差。但是若是咱們切換到其餘的標籤頁或者最小化時,咱們就可以看到,標題的閃動變慢了不少,差很少提高到1000ms左右了。ide
爲了更加準確的記錄時間間隔的變化,咱們特此將上面的代碼進行以下的補充,標題進行閃動時記錄當前的毫秒時間戳,同時標記出當前標籤頁可見時的狀態和不可見時的狀態【查看演示】:測試
1 // 標題閃動 2 function blinkTile(title, timeout){ 3 var self = this; 4 var timer = null; 5 var backup = document.title; 6 var last = 0; 7 var process = document.getElementById("process"); 8 9 self.init = function(title, timeou){ 10 if(title != undefined){ 11 self.title = title; 12 } 13 self.timeout = timeout == undefined? 500: timeout; 14 } 15 16 self.start = function(){ 17 self.stop(); 18 19 function blink(){ 20 document.title = document.title == backup? self.title : backup; 21 self.check(); 22 } 23 blink(); 24 timer = setInterval(blink, self.timeout); 25 } 26 27 28 29 self.stop = function(){ 30 if(timer != null){ 31 document.title = backup; 32 clearInterval(timer); 33 timer = null; 34 } 35 } 36 37 38 // 打印時間差,同時讓滾動條在最下邊 39 self.check = function(){ 40 var date = new Date(); 41 var now = date.getTime(); 42 var diff = now-last; 43 last = now; 44 process.innerHTML += '<p>'+now+' ('+diff+')</p>'; 45 process.scrollTop = process.scrollHeight; 46 } 47 48 self.init(title, timeout); 49 } 50 var blink = new blinkTile('【新消息】', 500); 51 blink.start(); 52 53 // 標籤頁的可見狀態 54 var hidden, state, visibilityChange; 55 if (typeof document.hidden !== "undefined") { 56 hidden = "hidden"; 57 visibilityChange = "visibilitychange"; 58 state = "visibilityState"; 59 } else if (typeof document.mozHidden !== "undefined") { 60 hidden = "mozHidden"; 61 visibilityChange = "mozvisibilitychange"; 62 state = "mozVisibilityState"; 63 } else if (typeof document.msHidden !== "undefined") { 64 hidden = "msHidden"; 65 visibilityChange = "msvisibilitychange"; 66 state = "msVisibilityState"; 67 } else if (typeof document.webkitHidden !== "undefined") { 68 hidden = "webkitHidden"; 69 visibilityChange = "webkitvisibilitychange"; 70 state = "webkitVisibilityState"; 71 } 72 73 var process = document.getElementById("process"); 74 // 添加監聽器,在title裏顯示狀態變化 75 document.addEventListener(visibilityChange, function() { 76 if(document[state]=="hidden"){ 77 process.innerHTML += '<p style="color:#f00;">====== 離開 ======</p>'; 78 }else{ 79 process.innerHTML += '<p style="color:#f00;">++++++ 回來 ++++++</p>'; 80 } 81 }, false);
運行後,咱們可以看到程序記錄下的數據有(如下僅是部分數據):this
1429547223336 (505) 1429547223837 (501) ====== 離開 ====== 1429547225296 (1459) 1429547226296 (1000) 1429547227296 (1000) 1429547228297 (1001) ++++++ 回來 ++++++ 1429547229137 (840) 1429547229637 (500)
咱們很清楚的看到,當標籤頁不可見時(「離開」後),時間差上升了1000ms左右;標籤頁可見時(「回來」後),時間差又恢復到了500ms左右。不過在標籤頁剛切換完的時候,時間差的變化比較大,後來就趨於穩定了。其實瀏覽器爲了在標籤頁不可見時減小CPU的利用率和電池等的消耗,特意將時間間隔進行提升。
不過這裏要指出的是,在IE11下,標籤的可見狀態不會影響定時器的時間間隔。
上面的代碼中,咱們設定的時間間隔是500ms,標籤頁不可見時,時間間隔就會提高到1000ms;若是咱們把時間間隔設定到1500ms呢,2500ms,能夠修改程序運行一下,是否能發現什麼規律。