跳至主要内容

[WebAPIs] 計時與動畫 Timer with setInterval, setTimeout, requestAnimationFrame

  • requestAnimationFrame:要自己 call 自己〈自體循環〉,才會有下一次。不用設時間,會根據執行時間的快慢(延遲)做調整。這是處理動畫首選。函式內預設就會產生 time 這個變數。
  • setTimeout
  • setInterval

window.requestAnimationFrame

// Polyfill for browser capability

var requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;

var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

requestAnimationFrame(animation); // 開始啟動 requestAnimationFrame

$('#stop').on('click', function () {
cancelAnimationFrame(requestID);
});

function animation(time) {
// Do whatever ...
console.log(time); // function 中可以代 time 就可以看到執行的時間點
requestID = requestAnimationFrame(animation);
}

如果想要停止該 function 繼續執行,一種是不要繼續在該函式呼叫 requestAnimationFrame,另一種則是使用 cancelAnimationFrame,後者記得要把每一次執行後的 requestID 都存起來。

使用例子 @ CodePen

window.setTimeout

利用 setTimeout(函數, 等待時間) 重複執行函數

var timerId;

function delayedAlert() {
timerId = window.setTimeout(slowAlert, 2000); // 設定計時器
}

function slowAlert() {
alert('That was really slow!');
}

function clearAlert() {
window.clearTimeout(timerId); // 清除計時器
}

代入參數(Passing Arguments)

如果有需要在 setTimeout,可以在代入時間的參數後再代入其他自訂的參數:

function animal(firstName, lastName = 'Chen') {
console.log(`${firstName} ${lastName}`);
}

setTimeout(animal, 500, 'Po Jung', 'Chen');

重複呼叫 setTimeout 參數(Recursive setTimeout Calls)

由於 setInterval 可能會在下一個還沒做完就做下一次,而且會超過時間〈延遲〉,所以也可以使用 Recursive setTimeout Calls:

let i = 0;

function increment() {
i++;
console.log(i);
}

let timer = setTimeout(function myTimer() {
increment();
timer = setTimeout(myTimer, 1000);
}, 1000);

// let's cancel after 7 seconds
setTimeout(() => {
console.log('Cancelling');
clearTimeout(timer);
}, 7000);

window.setInterval

  • 利用 setInterval(函數, 時間) 啟動
  • 利用 clearInterval(timerId) 停止計時
var intervalId;

function changeColor() {
intervalId = setInterval(flashText, 500); // 啟動計時器
}

function flashText() {
var oElem = document.getElementById('my_box');
oElem.style.color = oElem.style.color == 'red' ? 'blue' : 'red';
}

function stopTextColor() {
clearInterval(intervalId); // 清除計時器
}

參考