requestNextAnimationFrame
定义
告诉浏览器:你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下次重绘之前执行。
下次重绘之前?
原理
一般显示器都是 60Hz 的刷新率,即 1000ms 内刷新 60 次,每 16.7 毫秒刷新 1 次。rAF 的执行时机则是由系统来决定,(60Hz-->16.7ms / 75Hz-->13.3ms),rAF 的执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
和 setTimeout 的区别
执行时机
自动休眠
See the Pen jONBMMz by Ted.SZ (@tedsz1025) on CodePen.

假设屏幕是每隔 16.7ms 刷新一次,而 setTimeout 每隔 10ms 设置图像向左移动 1px,就会出现如下的绘制过程:
0ms: 未刷新,等待中,未执行;
10ms:未刷新,等待中,执行设置 left=1px;
16.7ms:刷新,图像向左移动 1px,未执行;
20ms:未刷新,等待中,执行设置 left=2px;
30ms: 未刷新,等待中,执行设置 left=3px;
33.4ms: 刷新,图像向左移动 3px,未执行;
...


rAF 使用场景
保障动画流畅执行
完成一些 CSS 不能完成的动画
保证图片渲染完成(连续调用两次)
项目中的使用
function Dom__onNextFrame(callback) {
// 需要两次确保一定是下一次渲染
var nextFrame = requestAnimationFrame;
var frameCount = 2;
return next();
function next() {
nextFrame(function() {
if (--frameCount) {
return next();
}
callback();
});
}
}实例
<img
id="img"
src="http://www.zmdz.com/bbs/incomefiles/20121/3110484797916.JPG"
style="width: 300px; height:300px; border: 1px solid red;"
onload="Dom__onNextFrame()"
/>
<div>step: <span id="step">waiting...</span></div>
<script>
var stepEl = document.querySelector('#step');
var img = document.querySelector('#img');
function Dom__onNextFrame() {
var frameCount = 2;
return next();
function next() {
requestAnimationFrame(function() {
alert('rAF');
if (--frameCount) {
return next();
}
changeStatus();
});
}
function changeStatus() {
stepEl.innerText = 'img loaded.';
console.log('img loaded.');
}
}
</script>Last updated
Was this helpful?

