使用 requestAnimationFrame

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

过去,JavaScript 中只有一种方法可以执行定时循环:setInterval()。如果您需要以相当快的速度重复某些操作(但不像 for 循环那样快),则可以使用它。为了动画的目的,目标是每秒六十“帧”以使其看起来流畅,因此您将运行如下循环:

setInterval(function() {
  // animiate something
}, 1000/60);

现在有了一个更好的替代方案。 Paul Irish 在 两年前引入了 requestAnimationFrame。我并没有太多要补充的,我只是之前从未真正使用过它,现在我使用了,所以我想帮助传播这个消息并撰写一篇关于其基本用法的文章。

为什么更好?

正如 Paul 所解释的

  • 浏览器可以对其进行优化,因此动画将更加流畅
  • 非活动选项卡中的动画将停止,从而使 CPU 能够保持闲置状态
  • 更节能

最简单的示例

function repeatOften() {
  // Do whatever
  requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);

调用它一次以启动它,然后您的函数会递归调用自身。

启动和停止

requestAnimationFrame 返回一个 ID,您可以使用它来取消它,就像 setTimeoutsetInterval 一样。此处使用的 jQuery 仅用于演示简单的动画和绑定事件。

var globalID;

function repeatOften() {
  $("<div />").appendTo("body");
  globalID = requestAnimationFrame(repeatOften);
}

$("#start").on("click", function() {
  globalID = requestAnimationFrame(repeatOften);
});

$("#stop").on("click", function() {
  cancelAnimationFrame(globalID);
});

此示例

Check out this Pen!

浏览器支持

请参阅 Can I Use… 表格。

唯一值得注意的问题是 IE 9-、iOS 5- 和 Android。但实际上这不是问题,因为

垫片

像许多高级 Web 功能一样,最好在可用时使用它,并在无法使用时回退到可用的内容。可能最好只是 参考此 Gist。只需在使用 requestAnimationFramecancelAnimationFrame 之前将其包含在任何位置即可。

使用此方法,您可以在任何浏览器中使用 requestAnimationFrame

稍微复杂的示例

我在制作一个简单的演示来更好地学习 canvas 时了解了这一点

查看 Chris Coyier 在 CodePen 上的笔 超简单的 requestAnimationFrame (@chriscoyier)。

实际上更复杂的是同时运行多个使用此方法的动画(仍然可以正常回退)。如果您知道一些示例,请随时在评论中链接这些内容。