是什么
requestAnimationFrame
window.requestAnimationFrame()
方法跟setTimeout
类似,都是推迟某个函数的执行。不同之处在于,setTimeout
必须指定推迟的时间,window.requestAnimationFrame()
则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16 ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,requestAnimationFrame()
会暂停执行。
如果某个函数会改变网页的布局,一般就放在 window.requestAnimationFrame()
里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。
示例
在这个例子中,一个元素的动画时间是 2 秒(2000 毫秒)。该元素以 0.1px/ms 的速度向右移动,所以它的相对位置(以 CSS 像素为单位)可以通过动画开始后所经过的时间(以 毫秒)的函数来计算 0.1 * elapsed
。该元素的最终位置是在其初始位置的右边 200px(0.1 * 2000
)。
const element = document.getElementById("some-element-you-want-to-animate");
let start, previousTimeStamp;
let done = false;
function step(timestamp) {
if (start === undefined) {
start = timestamp;
}
const elapsed = timestamp - start;
if (previousTimeStamp !== timestamp) {
// 这里使用 Math.min() 确保元素在恰好位于 200px 时停止运动
const count = Math.min(0.1 * elapsed, 200);
element.style.transform = `translateX(${count}px)`;
if (count === 200) done = true;
}
if (elapsed < 2000) {
// 2 秒之后停止动画
previousTimeStamp = timestamp;
if (!done) {
window.requestAnimationFrame(step);
}
}
}
window.requestAnimationFrame(step);