8

我正在尝试使用新的 ng-animate 指令,并且在与 ng-repeat 一起使用时正在努力获得预期的效果。我试图让物品在进入时变大,在离开时缩小。到目前为止,输入工作正常,但收缩动画失败。

我在这里设置了一个小提琴,所以你可以看到我的问题:-

http://jsfiddle.net/rpk98c/6t42M/1/

相关的 HTML 是:-

<ul>
    <li ng-animate="{enter: 'repeat-enter',
                    leave: 'repeat-leave',
                    move: 'repeat-move'}" ng-click="remove($index)" ng-repeat="name in names">{{name}}</li>
</ul>

以及相关的CSS:-

.repeat-enter-setup, .repeat-leave-setup, .repeat-move-setup {
-webkit-transition:all linear 1s;
-moz-transition:all linear 1s;
-ms-transition:all linear 1s;
-o-transition:all linear 1s;
transition:all linear 1s;
}

.repeat-enter-setup {
    max-height: 0;
    opacity:0;
}
.repeat-enter-setup.repeat-enter-start {
    max-height: 250px;
    opacity:1;
}
.repeat-leave-setup {
    opacity:1;
    max-height: 250px;
}
.repeat-leave-setup.repeat-leave-start {
    opacity:0;
    max-height: 0;
}

有谁知道我哪里出错了?

谢谢,

瑞安

ps 刚刚注意到在 IE 10 中没有动画效果!我现在正在 Chrome 中测试

4

3 回答 3

7

您需要切换 css 的第一行以影响“开始”类而不是设置类。我知道,这不是他们做例子的方式,但它会起作用。所以让它:

.repeat-enter-start, .repeat-leave-start, .repeat-move-start {
  -webkit-transition:all linear 1s;
  -moz-transition:all linear 1s;
  -ms-transition:all linear 1s;
  -o-transition:all linear 1s;
  transition:all linear 1s;
}

这很有帮助,因为您正在尝试为元素通常不具备的属性设置动画。元素通常根本不会设置 max-height 属性。因此,当您在转换的同时应用最大高度时,它将动画化您添加属性的事实!这是在甚至应用“开始”类之前,这意味着设置阶段不会在开始阶段开始之前完成(因为动画需要 1 秒)。因此,当您应用“离开”动画时,将发生以下步骤。

  1. 您的元素开始时没有最大高度。
  2. 应用“离开设置”类并为您提供最大高度和过渡。
  3. 因为 max-height 刚刚“更改”(从不存在到存在)并且您有一个过渡,浏览器现在将开始将 max-height 从某个默认起始值​​(看起来为 0)动画到您选择的 250px 值,所以元素立即缩小到 0 并开始动画!
  4. 现在应用了“离开开始”类,但第 3 步还没有完成!最大高度仍为 0 或接近,因为它仍在忙于动画插入属性,所以动画只是停止并再次变为 0,我们什么也看不到。

但是如果我们将转换属性从“设置”步骤移动到“开始”步骤,就像上面的 CSS 一样,步骤 3 将是即时的,因为它没有转换。过渡首先出现在第 4 步。所以我们有:

  1. 您的元素开始时没有最大高度。
  2. 应用“离开设置”类并为您提供最大高度但不提供过渡。
  3. 我们没有过渡,因此最大高度立即更改为 250px。
  4. 现在应用了“leave-start”类,并且由于这次第 3 步完成,最大高度现在是 250px,我们可以在没有问题的情况下进行动画处理。

不透明度没有这个问题,因为您是从默认值 1 开始制作动画的,在第 3 步中没有动画阻碍。似乎输入事件的处理方式有些不同,因为它们更有可能从非默认值设置动画,因此您不会在任何事件中看到此行为。

编辑:

我对此进行了更多试验,结果发现我的答案不适用于 Firefox(至少不适用于 FF Windows)。首先,如果您为不存在的属性设置动画,FF 似乎会直接失败,因此您需要确保您的元素从一开始就具有最大高度,例如:

li {
    max-height: 250px;
}

这个修复留给我,但由于某种原因,在 Windows 上的 Firefox 中根本没有输入动画。仍在试图弄清楚这一点。

于 2013-05-23T11:36:54.780 回答
0

我不确定为什么要指定max-height. 您可以省略所有高度规范,它似乎工作。

.repeat-enter-setup, .repeat-leave-setup, .repeat-move-setup {
-webkit-transition:all linear 1s;
-moz-transition:all linear 1s;
-ms-transition:all linear 1s;
-o-transition:all linear 1s;
transition:all linear 1s;
}

.repeat-enter-setup {
    opacity:0;
}
.repeat-enter-setup.repeat-enter-start {
    opacity:1;
}
.repeat-leave-setup {
    opacity:1;
}
.repeat-leave-setup.repeat-leave-start {
    opacity:0;
}
于 2013-05-15T00:31:29.050 回答
0

接受的答案现在有点过时了,但当我解决同样的问题时它仍然非常有帮助。limitTo这是使用最新版本的 ng-animate 和过滤器的展开/折叠功能的示例ng-repeat

HTML:

<div ng-init="listLimit = 3">
    <div class="expander" ng-repeat="item in list | limitTo: listLimit">
        {{ item }}
    </div>
    <div ng-click="listLimit === 3 ? listLimit = list.length : listLimit = 3">
        <span ng-if="listLimit === 3">more</span>
        <span ng-if="listLimit !== 3">less</span>
    </div>
</div>

CSS:

.expander {
  max-height: 250px;
  opacity: 1;
  transition: all linear 0.8s;
}

.expander.ng-enter {
  max-height: 0;
  opacity: 0;
}

.expander.ng-enter-active {
  max-height: 250px;
  opacity: 1;
}

.expander.ng-leave {
  max-height: 250px;
  opacity: 1;
}

.expander.ng-leave-active {
  max-height: 0;
  opacity: 0;
}
于 2016-11-17T18:29:00.267 回答