window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
备注: 若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用requestAnimationFrame()。requestAnimationFrame() 是一次性的。
requestAnimationFrame接受一个函数,并且会为该函数传递一个DOMHighResTimeStamp类型参数;
DOMHighResTimeStamp 是一个 double 类型,用于存储毫秒级的时间值。
为了提高性能和电池寿命,在大多数浏览器里,当 requestAnimationFrame() 运行在后台标签页或者隐藏的 <iframe> 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。这也是为什么我们一般使用requestAnimationFrame代替定时器去做动画。
下面是一个使用requestAnimationFrame实现动画的实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<img
id="some-element-you-want-to-animate"
style="height: 100px; width: auto"
src="https://mass-office.alipay.com/huamei_koqzbu/afts/img/y1GeSIThj4QAAAAAAAAAABAADnV5AQBr/original"
alt=""
/>
<script>
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);
</script>
</body>
</html>