官方讲解:window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
简单的说就是css渲染前调用。很好理解,如对比setInterval运行后去更新页面,同样的rAF也是运行后更新页面。
(图中S:收集css数据 ,L:创建渲染树,找出页面上所有数据以及元素位置,P:创建实际像素数据,绘制内容到页面。)
setInterval对比rAF
setInterval:问题一,动画的循时间环间隔不好确定。问题二,代码执行会进任务线程队列中,如果线程处于忙碌状态,那么动画不会立刻执行。问题三,页面被隐藏或最小化时,仍在后台执行动画任务。
rAF:好处一,CPU节能,页面处于未激活的状态下,rAF也会停止渲染。好处二,高频刷新下,可保证每次绘制间隔内,函数只被执行一次,保证流畅性,节省函数执行的开销。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
html, body{
height: 100vh;
}
</style>
<body>
<div style="height: 200%;width: 500;margin:0 auto;">滚动</div>
<script>
let scrollTop = document.documentElement.scrollTop
let scrollHeight = document.documentElement.scrollHeight
let winHeight = window.innerHeight
let animation = null
function step() {
console.log(scrollTop)
if(scrollTop + winHeight < scrollHeight){
scrollTop = scrollTop + 1
document.documentElement.scrollTop = scrollTop
animation = requestAnimationFrame(step);
} else {
cancelAnimationFrame(animation)
}
}
requestAnimationFrame(step)
</script>
</body>
</html>