CSS 动画与 JavaScript 动画

您可以使用 CSS 或 JavaScript 制作动画。您应该使用哪种方式?为什么?

在网页上创建动画主要有两种方法:使用 CSS 和使用 JavaScript。您选择哪种方法实际上取决于项目的其他依赖项,以及您尝试实现的效果类型。

摘要

  • 使用 CSS 动画实现更简单的“一次性”例如切换界面元素状态。
  • 如果需要高级效果(例如弹跳、停止、暂停、快退或减速),请使用 JavaScript 动画。
  • 如果您选择使用 JavaScript 来制作动画,请使用 Web Animations API 或您喜欢的现代框架。

大多数基本动画可以使用 CSS 或 JavaScript 来创建,但工作量和时间会有所不同(另请参阅 CSS 对比 JavaScript 性能)。每种方法各有利弊,但以下都是很好的指导原则:

  • 当您为界面元素采用较小的独立状态时,请使用 CSS。CSS 过渡和动画非常适合从侧面引入导航菜单,或显示提示。您最终可能会使用 JavaScript 来控制状态,但动画本身是在 CSS 中。
  • 在需要对动画进行大量控制时,使用 JavaScript。Web Animations API 是基于标准的方法,目前在大多数现代浏览器中都可以使用。这可以提供真实对象,非常适合复杂的面向对象的应用。在需要停止、暂停、减速或倒退动画时,JavaScript 也非常有用。
  • 如果您想手动编排整个场景,请直接使用 requestAnimationFrame这是一种高级 JavaScript 方法,但如果您构建游戏或绘制到 HTML 画布,则该方法非常有用。

或者,如果您已在使用包含动画功能的 JavaScript 框架(例如通过 jQuery 的 .animate() 方法或 GreenSock 的 TweenMax),那么您可能会发现,继续使用该框架来处理动画在总体上会更加方便。

利用 CSS 编写动画

使用 CSS 制作动画是让内容在屏幕上移动的最简单方式。此方法称为声明式,因为您可以指定您希望发生的情况。

下面是一些在 X 轴和 Y 轴上移动元素 100px 的 CSS。具体方法是使用 CSS 转场效果,将其设置为采用 500ms。添加 move 类后,transform 值会发生变化并开始转换。

.box {
  transform: translate(0, 0);
  transition: transform 500ms;
}

.box.move {
  transform: translate(100px, 100px);
}

试试看

除了过渡的持续时间之外,还有一些加/减速选项,加/减速基本上就是动画的感觉。如需详细了解缓动,请参阅缓动基础知识指南。

如上述代码段所示,如果您创建了单独的 CSS 类来管理动画,则可以使用 JavaScript 打开和关闭每个动画:

box.classList.add('move');

这样做可以为您的应用带来很好的平衡。您可以专注于使用 JavaScript 管理状态,只需在目标元素上设置适当的类,让浏览器处理动画。如果您按照这种方法,您可以监听元素上的 transitionend 事件,但前提是您能够放弃对旧版 Internet Explorer 的支持;版本 10 是支持这些事件的第一个版本。所有其他浏览器均已支持该事件一段时间。

监听过渡结束所需的 JavaScript 如下所示:

var box = document.querySelector('.box');
box.addEventListener('transitionend', onTransitionEnd, false);

function onTransitionEnd() {
    // Handle the transition finishing.
}

除了使用 CSS 转场效果之外,您还可以使用 CSS 动画,这让您能够更好地控制个别动画的关键帧、持续时间和迭代。

例如,您可以采用与转换相同的方式为框添加动画效果,但要让它在没有任何用户互动(如点击)和无限重复的情况下进行动画处理。您还可以同时更改多个属性。

.box {
  animation-name: movingBox;

  animation-duration: 1300ms;

  animation-iteration-count: infinite;

  animation-direction: alternate;
}

@keyframes movingBox {
  0% {
    transform: translate(0, 0);
    opacity: 0.3;
  }

  25% {
    opacity: 0.9;
  }

  50% {
    transform: translate(100px, 100px);
    opacity: 0.2;
  }

  100% {
    transform: translate(30px, 30px);
    opacity: 0.8;
  }
}

试试看

借助 CSS 动画,您可以独立于目标元素定义动画本身,并使用 animation-name 属性选择所需的动画。

如果您希望 CSS 动画在旧版浏览器上也能正常运行,则需要添加供应商前缀。许多工具可帮助您创建所需的 CSS 前缀版本,让您可以在源文件中编写无前缀版本。

利用 JavaScript 和 Web Animations API 编写动画

相比之下,使用 JavaScript 创建动画比编写 CSS 转换或动画更复杂,但它通常会为开发者提供更多功能。您可以使用 Web Animations API 为特定 CSS 属性添加动画效果或构建可组合的效果对象。

JavaScript 动画是命令式的,因为您需要将其作为代码的一部分以内嵌方式编写。您还可以将它们封装在其他对象中。您需要编写以下 JavaScript 来重新创建之前所述的 CSS 转换:

var target = document.querySelector('.box');
var player = target.animate([
    {transform: 'translate(0)'},
    {transform: 'translate(100px, 100px)'}
], 500);
player.addEventListener('finish', function() {
    target.style.transform = 'translate(100px, 100px)';
});

默认情况下,Web Animations 仅修改元素的呈现方式。如果您希望对象保持在其移动到的位置,则应在动画播放完毕后,按照我们的示例修改其底层样式。

试试看

Web Animations API 是来自 W3C 的一个相对较新的标准。大多数现代浏览器都原生支持该 API。对于不支持的现代浏览器,可以使用 polyfill

借助 JavaScript 动画,您可以完全控制元素在每个步骤的样式。这意味着您可以在您认为合适时减慢动画、暂停动画、停止动画、倒退动画以及操纵元素。如果您正在构建复杂的对象导向型应用,这将特别有用,因为您可以正确封装您的行为。