再看別人實現粒子效果的時候會有以下程式碼:
window.requestAnimationFrame || (window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame || wins.
return window.setTimeout(function() {
return callback( new Date());
}, 1000 / 60)
});
});
這個到底是什麼意思,它又是怎麼用的呢?
window.requestAnimationFrame 告訴瀏覽器您要執行的動畫並且請求瀏覽器的在下一個動畫幀重繪視窗。該方法在瀏覽器重繪之前作為一個回調函數被呼叫。
就是告訴瀏覽器在刷新畫面的時候,呼叫這個方法。 window.requestAnimationFrame的前世今生
:
在90年代,那個互聯網做廣告的年代,window上面各種走馬燈,各種狀態文字都是用setTimeout來時實現的,如下: 複製程式碼
程式碼如下:
(function((){
function update(){
setTimeout(update,1000)
}
setTimeout(update,1000)
})();
(function(){
function update( {
//
}
setInterval(update,1000)
})();
動畫的問題最棘手的是延遲問題,對於顯示器來說,每一秒60幀頻,如果我們按照瀏覽器的刷新速率來控制我們的動畫時間的話會有很好的效果,即17ms,setTimeout(callback,1000/60),但是:
1.各個瀏覽器及時精度是不一樣的。
2.對於setTimeout 和setInterval 實作機制並不是我們需要的那樣,當經過特定的時間後,瀏覽器會將那部分程式碼加入到UI的繪製佇列當中,如果這個時候UI執行緒很忙,有其它的任務阻塞,動畫的下一幀就不會準時執行。經過長時間的累計堆加之後,可能我們偏離原來的時間點誤差越來越大。
Mozilla 的 Robert O'Callahan 在思考這個問題,並想出了一個獨特的方案。他指出CSS transitions 和 animations的優勢在於瀏覽器知道哪些動畫會發生,所以得到正確的間隔來刷新UI。而javascript動畫,瀏覽器也不知道動畫正在發生。他的解決方案是創建一個mozRequestAnimationFrame()方法來告訴瀏覽器哪些javascript程式碼正在執行,這使得瀏覽在執行一些程式碼後得到最佳化。
mozRequestAnimationFrame()方法接受一個參數,是一個螢幕重繪前被呼叫的函數。這個函數用來對產生下合適的dom樣式的改變,這些改變用在下一次重繪中。你可以像呼叫setTimeout()一樣的方式鍊式呼叫mozRequestAnimationFrame()。
這就是window.requestAnimationFrame的由來。 在Mozilla官網看到如下
Because this technology's specification has not stabilized, check the compatibility table for the proper prefixes to not stabilized, check the compatibility table for the proper prefixes to not stabilized, check the compatibility table for the proper prefixes to not stabilized, check the compatibility table for the proper prefixes to havuse in axbe broce. of an experimental technology is subject to change in future version of browsers as the spec changes. 由於這項技術的規範還沒有穩定,正確的前綴使用在各種瀏覽器的兼容性表。也要注意的是語法和行為的實驗技術是如有改變,在未來版本的瀏覽器的規格變化。 目前在Android系統下方是不支援的,動畫只能setTimeout咯。