再看別人實現粒子效果的時候會有以下代碼:
復制代碼 代碼如下:
window.requestAnimationFrame || (window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback, element) {
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 use in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.
由於這項技術的規范還沒有穩定,正確的前綴使用在各種浏覽器的兼容性表。還要注意的是語法和行為的實驗技術是如有改變,在未來版本的浏覽器的規格變化。
目前在Android系統下是不支持的,動畫只能setTimeout咯。