Skip to content
Mithril.js 2
Main Navigation 指南API

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

主题

Sidebar Navigation

入门

安装

简单应用

资源

JSX

在旧版浏览器上使用 ES6+

动画

测试

示例

第三方库集成

路径处理

关键概念

虚拟 DOM

组件

生命周期方法

键(Key)

自动重绘系统

杂项

框架对比

从 v1.x 迁移

从 v0.2.x 迁移

API

页面导航

动画 ​

技术选型 ​

动画常被用于增强应用程序的生动性。现代浏览器对 CSS 动画提供了良好的支持,并且有各种各样的 库可以实现快速的、基于 JavaScript 的动画。如果你对新技术感兴趣,还可以关注即将推出的 Web Animations API 及其 polyfill。

Mithril.js 本身没有提供任何动画 API,因为现有的这些选项已经足以实现丰富且复杂的动画效果。然而,Mithril.js 提供了生命周期钩子函数,在某些传统上难以实现动画的特定情况下,可以简化操作。

元素创建时的动画 ​

当元素被创建时,通过 CSS 为元素添加动画非常简单。只需像往常一样将动画添加到 CSS 类中:

css
.fancy {
  animation: fade-in 0.5s;
}
@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
javascript
var FancyComponent = {
  view: function () {
    return m('.fancy', 'Hello world');
  },
};

m.mount(document.body, FancyComponent);

元素移除时的动画 ​

在移除元素前添加动画的关键在于,必须等待动画结束后才能真正移除该元素。幸运的是,Mithril.js 提供了 onbeforeremove 钩子,允许我们延迟元素的移除。

让我们创建一个 exit 动画,将 opacity 从 1 渐变为 0。

css
.exit {
  animation: fade-out 0.5s;
}
@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

现在我们创建一个简单的组件,用于显示和隐藏上一节中创建的 FancyComponent。

javascript
var on = true;

var Toggler = {
  view: function () {
    return [
      m(
        'button',
        {
          onclick: function () {
            on = !on;
          },
        },
        'Toggle'
      ),
      on ? m(FancyComponent) : null,
    ];
  },
};

接下来,让我们修改 FancyComponent,使其在移除时淡出:

javascript
var FancyComponent = {
  onbeforeremove: function (vnode) {
    vnode.dom.classList.add('exit');
    return new Promise(function (resolve) {
      vnode.dom.addEventListener('animationend', resolve);
    });
  },
  view: function () {
    return m('.fancy', 'Hello world');
  },
};

vnode.dom 指向组件的根 DOM 元素(<div class="fancy">)。我们在这里使用 classList API 将 exit 类添加到 <div class="fancy">。

然后我们返回一个 Promise,该 Promise 会在 animationend 事件触发时变为 resolved 状态。当我们从 onbeforeremove 返回一个 promise 时,Mithril.js 会等待直到 promise 被 resolve,才会移除该元素。在此例中,它会等待退出动画完成。

我们可以通过挂载 Toggler 组件来验证进入和退出动画是否都有效:

javascript
m.mount(document.body, Toggler);

请注意,onbeforeremove 钩子仅在元素从 DOM 中分离时触发,即当元素失去其 parentNode 时。这种行为的设计目的是为了避免潜在的突兀用户体验,例如页面上所有可能的退出动画都在路由更改时运行。如果退出动画没有生效,请确保将 onbeforeremove 处理程序绑定到尽可能高的层级,以确保动画代码能够被执行。

性能 ​

在创建动画时,建议仅使用 opacity 和 transform CSS 规则,因为这些规则可以由现代浏览器进行硬件加速,并且比动画 top、left、width 和 height 具有更好的性能。

还建议避免使用 box-shadow 规则以及类似 :nth-child 的选择器,因为它们都是资源密集型的选项。如果需要为 box-shadow 添加动画效果,可以考虑将 box-shadow 规则应用于一个伪元素,并修改该伪元素的 opacity 属性。其他可能造成性能开销的因素包括大型或动态缩放的图片,以及 position 属性值不同的重叠元素(例如,一个绝对定位元素覆盖在一个固定定位元素之上)。

Pager
上一页在旧版浏览器上使用 ES6+
下一页测试

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors

https://mithril.js.org/animation.html

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors