setInertval間隔時間問題

假設我們有一個滾動條長爲50px,我們想要設置在兩秒內滾動到終點。

<div id='slide'>

<div id='move'></div>

</div>

一般情況下

我們想要move模塊在兩秒內從slide最左邊滑動到最右邊,相當於一個動畫;一般我們去用setInterval解決方式如下:

var move=document.getElementById("move");

var interval=window.setInterval(function(){

var left=parseFloat(document.getElementById('move').style.left);

left<50?move.style.left=left+1+"px":clearInterval(interval);

},40);

在這裏我們將2s轉化爲2000ms對應50px,相當於40ms對應一個像素。於是將間隔時間設置爲40ms;這樣一來每隔40ms move模塊就會向右滑動一個像素。

理想很豐滿,現實很骨感。。。

現在很多瀏覽器都將setInterval間隔時間設置了最小值,尤其是你當將頁面隱藏或者最小化時候,很多瀏覽器會將你設置的間隔時間修改爲1000ms(如果間隔時間小於1000ms);

這樣的話本來兩秒鐘我們認爲能執行完的事件,如果一開始就將其最小化,那麼會執行1000/40倍也就是會花費25*2秒。明白了不?

換句話說 瀏覽器會將你的間隔時間變大,導致你裏面事件執行的間隔變大。但是裏面事件是由時間間隔驅動的,多久執行一次都會+1像素。

所以這樣就導致了問題的出現----如何預防間隔時間不準確?

其實目前很多動畫的實現都不會簡單去應用上述的寫法。就跟看視頻一樣,間隔一段時間回去頁面再看時候 大部分都是乍一看還在離開時候,然後突然就會跳到現在應該播放的幀而不會“慢放”。

所以我們應該不去考慮到底設計間隔多久而應該考慮 多久能執行完。不知道繞暈了沒??哈哈

解釋一下:setInterval裏面的函數執行事件 是基於你設定的間隔去執行事件,如果我們太過於依賴於間隔(如上例子)就會導致上述問題(我們事件都是基於間隔去計算的)。

所以我們應該不去管間隔到底是多少毫秒(當然你不能將間隔設置的不靠譜,本來2s執行完的動畫 1s動一下估計就啪啪兩下到頭了,很是不舒服)而應該像視頻播放一樣去設計我們的定時器:

在正常間隔執行事件下去正常執行事件,在間隔被擴大後我們在事件內部處理這個時間段到底應該走到了哪裏!看代碼:

var move=document.getElementById('move'),start=new Date().getTime(),end=2000,

var inter=window.setInterval(function(){

var now=new Date().getTime(),space=now-start, left=parseFloat(document.getElementById('move').style.left);

left<50?move.style.left=(space-start)/40+'px':clearInterval(inter);

},40)

上面代碼在事件中增加了對當前時間以及開始時間的計算,用這種方式去輔助間隔時間引起的bug問題。也就是說在正常情況下上述代碼是40ms走1個像素,2s正好會到達50px。當瀏覽器將間隔變大後,假設瀏覽器將間隔修改爲1000ms,並且一開始就修改了。

這樣我們在一秒之後回去看的時候進度條就會根據事件的時間去計算1s內到底應該走到哪,這樣就會跟視頻播放一樣的效果,進度條不會滯後,也不會因爲間隔邊長引起的事件處理bug。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章