requestAnimationFrame(rAF)是专为JavaScript动画设计的API,它在下一次屏幕重绘前执行回调,比setInterval更精准节能;需递归调用自身实现持续动画,并推荐基于时间戳计算位移以保障匀速。

JavaScript 动画的核心是让元素在短时间内连续、平滑地更新样式,requestAnimationFrame(简称 rAF)就是为这个目的专门设计的 API —— 它让浏览器决定何时执行动画帧,比 setTimeout 或 setInterval 更精准、更节能、更契合屏幕刷新节奏。
为什么用 requestAnimationFrame 而不是 setInterval?
浏览器通常以约 60fps(每秒 60 帧)刷新画面,即每 ~16.7ms 渲染一帧。rAF 会自动把回调函数安排在**下一次屏幕重绘之前**执行,保证动画与刷新率同步;而 setInterval(fn, 16) 只是“尽力每 16ms 调用一次”,实际可能跳帧、卡顿,还可能在页面不可见时继续运行,浪费资源。
requestAnimationFrame 的基本用法
rAF 接收一个回调函数,返回一个 ID(类似 setTimeout),可用于取消动画:
- 调用
requestAnimationFrame(callback)启动动画帧 - 回调函数中更新元素状态(如位置、透明度)
- 若需持续动画,在回调里**递归调用自身**(这是关键!)
- 用
cancelAnimationFrame(id)中止动画
示例:让一个 div 水平移动 200px
立即学习“Java免费学习笔记(深入)”;
const box = document.getElementById('box');
let pos = 0;
let animationId;
function animate() {
pos += 2;
if (pos >= 200) {
box.style.left = '200px';
return; // 动画结束,不继续调用
}
box.style.left = pos + 'px';
animationId = requestAnimationFrame(animate); // 下一帧继续
}
animationId = requestAnimationFrame(animate);
云模块网站管理系统3.1.03
云模块_YunMOK网站管理系统采用PHP+MYSQL为编程语言,搭载自主研发的模块化引擎驱动技术,实现可视化拖拽无技术创建并管理网站!如你所想,无限可能,支持创建任何网站:企业、商城、O2O、门户、论坛、人才等一块儿搞定!永久免费授权,包括商业用途; 默认内置三套免费模板。PC网站+手机网站+适配微信+文章管理+产品管理+SEO优化+组件扩展+NEW Login界面.....目测已经遥遥领先..
下载
// 暂停/取消示例:
// cancelAnimationFrame(animationId);
结合时间控制实现匀速动画(推荐)
上面例子是“每帧固定位移”,但不同设备帧率可能波动(比如低端机掉到 30fps),导致速度不一致。更健壮的做法是基于**时间差**计算位移:
- 记录上一帧的时间戳(由 rAF 回调自动传入)
- 当前帧减去上一帧,得到真实经过的毫秒数
- 按目标速度(如 100px/s)乘以该时间,得出本次应移动距离
示例(匀速移动 200px,耗时 2 秒):
const box = document.getElementById('box');
const duration = 2000; // 总时长 ms
const targetX = 200;
let startTime = null;
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1); // 0~1
const currentX = progress * targetX;
box.style.transform = translateX(${currentX}px);
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
实用建议和注意事项
- 优先使用
transform和opacity动画属性,它们能触发 GPU 加速,性能远好于修改left/top或width/height - 避免在动画帧中频繁读取布局属性(如
offsetTop、getBoundingClientRect),会触发强制同步布局(layout thrashing) - rAF 在页面后台标签页中会自动降频或暂停,这是优点;如需后台运行(极少见),得配合 Page Visibility API 判断
- 现代开发中,复杂动画可考虑 CSS @keyframes +
element.animate(),但 rAF 仍是底层控制、物理模拟(如缓动、拖拽、粒子)的首选
基本上就这些。掌握 rAF 的递归调用逻辑和时间驱动思维,就能写出流畅、兼容、可维护的 JS 动画。










