在 HTML5 的時代裏我們可以通過 css3 的 animation 和 kerframes 配合使用動畫;也可以使用 css 的 transform 控制動畫;在 JS 裏面我們通常用 setTimeout 和 setInterval 來控制動畫時間。setTimeout 和 setInterval 對於控制動畫時間不是很準確,因爲它是靠電腦的刷新頻率。並且當瀏覽器切換到其他頁面或者最小化的時候動畫還在執行並不會停止,顯然是在做一些無用功。接下來要介紹一個新的特性,並且主流瀏覽器都對他進行了支持。
requestAnimationFrame
來看看 MDN 對它的介紹
window.requestAnimationFrame() 方法告訴瀏覽器您希望執行動畫並在瀏覽器在下一次重繪之前調用指定的函數來更新動畫。該方法使用一個回調函數作爲參數,這個回調函數會在瀏覽器重繪之前調用。
注意:若您想在下次重繪時產生另一個動畫畫面,您的回調例程必須調用 requestAnimationFrame()
當你需要更新屏幕畫面時就可以調用此方法。在瀏覽器下次重繪前執行回調函數。回調的次數通常是每秒60次,但大多數瀏覽器通常匹配 W3C 所建議的刷新頻率。在大多數瀏覽器裏,當運行在後臺標籤頁或者隱藏的裏時,
requestAnimationFrame()
會暫停調用以提升性能和電池壽命。回調函數會被傳入一個參數,
DOMHighResTimeStamp
,指示當前被requestAnimationFrame()
排序的回調函數被觸發的時間。即使每個回調函數的工作量的計算都花了時間,單個幀中的多個回調也都將被傳入相同的時間戳。該時間戳是一個十進制數,單位毫秒,最小精度爲1ms(1000μs)。
語法
window.requestAnimationFrame(callback)
參數:
callback 一個指定回調函數形式的參數。該函數在下次重繪動畫時調用。這個回調函數只有一個參數 : DOMHighResTimeStamp ,指示 requestAnimationFrame() 開始觸發回調函數的當前時間 (preformance.now() 返回的時間)
返回值:
一個 long 整數,請求 ID,是回調列表中的唯一標識。是個非零值。後續可以作爲 window.cancelAnimationFrame() 以取消回調函數。
Demo
<html>
<head>
<meta charset="utf-8">
<title>動畫</title>
</head>
<body>
<div id="test" style="width:1px;height: 17px;background: #0f0;">0%</div>
<input type="button" value="Run" id="run" >
</body>
<script>
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.mzRequestAnimationFrame;
var start = null;
var ele = document.getElementById("test");
var progress =0;
function step(timestamp){
console.log("step" + timestamp);
progress += 1;
ele.style.width = progress + "%";
ele.innerHTML = progress + "%";
if (progress < 100) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
document.getElementById("run").addEventListener("click", function(){
console.log("run");
ele.style.width = "1px";
progress = 0;
requestAnimationFrame(step);
},false);
</script>
</html>