window.requestAnimationFrame()
方法跟setTimeout
类似,都是推迟某个函数的执行。不同之处在于,setTimeout
必须指定推迟的时间,window.requestAnimationFrame()
则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,requestAnimationFrame()
会暂停执行。
如果某个函数会改变网页的布局,一般就放在window.requestAnimationFrame()
里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。
该方法接受一个回调函数作为参数。
window.requestAnimationFrame(callback)
上面代码中,callback是一个回调函数。callback执行时,它的参数就是系统传入的一个高精度时间戳(performance.now()
的返回值),单位是毫秒,表示距离网页加载的时间。
window.requestAnimationFrame()
的返回值是一个整数,这个整数可以传入window.cancelAnimationFrame()
,用来取消回调函数的执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>requestAnimationFrame</title>
<style>
#animate {
width: 100px;
height: 100px;
position: absolute;
background-color: gray;
word-break: break-all;
}
</style>
</head>
<body>
<div id="animate">requestAnimationFrame</div>
<script>
var animate = document.querySelector("#animate");
console.dir(animate);
var start = null;
function step(timestamp) {
console.log(timestamp);
if (!start) start = timestamp ;
var progress = timestamp - start;
//获取CSS外部样式,IE使用currentStyle,非IE使用getComputedStyle()
var style = animate.currentStyle ? animate.currentStyle : document.defaultView.getComputedStyle(animate, null);
console.log(style.backgroundColor);
var rgb = style.backgroundColor;
//判断是否是rgb值,如果是取出相应的rgb
var res = /^rgb\((\d+), (\d+), (\d+)\)$/.exec(rgb);
//rgb转16进制
function rgbToHex(r, g, b) { return ((r << 16) | (g << 8) | b).toString(16); }
var hex = null;
if (res) {
hex = rgbToHex(res[1], res[2], res[3]);
} else {
hex = rgb.substr(1);
}
//var r_hex = (parseInt(hex) + (10000 - Math.floor(Math.random() * 20000)));
animate.style.backgroundColor = "#" + Math.floor(Math.random() * 100000);
animate.style.left = Math.min(progress / 10, 200) + 'px';
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
</script>
</body>
</html>
上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。