AngularJS css 动画 + 完成回调

Posted

技术标签:

【中文标题】AngularJS css 动画 + 完成回调【英文标题】:AngularJS css animation + done callback 【发布时间】:2014-01-16 16:44:41 【问题描述】:

我正在使用 AngularJS,并希望在动画完成时收到通知。我知道这可以通过像 myApp.animation(...) 这样的 javascript 定义的动画来完成,但我很好奇我是否可以在没有 javascript 的情况下做到这一点。

问题:是否可以使用角度ng-enterng-leave css-transitions,并指定完成回调?我猜animationend 事件被触发了,所以应该有办法做到这一点。

我有这个:

HTML:

<div ng-if="item" class="myDiv">  item.name  </div>

CSS:

.myDiv.ng-enter ...
.myDiv.ng-enter.ng-enter-active ...
.myDiv.ng-leave ...
.myDiv.ng-leave.ng-leave-active ...

我想在动画完成时调用myDone()(即在删除ng-enter-active 类之后)。

【问题讨论】:

是的,该活动有效。我建议您阅读以下内容:github.com/angular-ui/bootstrap/blob/master/src/transition/… 这是一个运行动画并在动画结束时收到通知的工厂。了解这个想法并尝试将其应用到您的用例中。 【参考方案1】:

是的,您可以使用$animate 服务,这通常在自定义指令中完成。一个简单的动画案例是在点击时以某种方式为元素设置动画。比如说,在点击时移除一个元素,使用 .ng-leave 指定动画,传递一个回调

app.directive('leaveOnClick', function($animate) 
  return 
    scope: 
      'leaveOnClick': '&'
    ,
    link: function (scope, element) 
      scope.leaveOnClick = scope.leaveOnClick || (function() );
      element.on('click', function() 
        scope.$apply(function() 
          $animate.leave(element, scope.leaveOnClick);
        );
      );
    
  ;
);

可以这样使用:

<div class="my-div" leaveOnClick="done()">Click to remove</div>

用 CSS 淡出元素:

.my-div.ng-leave 
  opacity: 1;
  transition: opacity 1s;
  -webkit-transition: opacity 1s;

.my-div.ng-leave.ng-leave-active 
  opacity: 0;

你可以看到the above animation in action at this Plunker。

但是,据我所知,ngIf 没有任何挂钩来传递回调,因此您必须编写自己的指令。以下是对a modified version of ngIf的描述,最初是从ngIf source复制而来,并重命名为animatedIf。它可以用于:

<div class="my-div" animated-if="shown" animated-if-leave-callback="leaveDone()" animated-if-enter-callback="enterDone()" >Some content</div>

它的工作方式是使用手动观察器来响应传递给animated-if 的表达式的变化。与原始 ngIf 的主要区别在于添加了一个“范围”参数来传递回调:

scope: 
  'animatedIf': '=',
  'animatedIfEnterCallback': '&',
  'animatedIfLeaveCallback': '&'
,

然后修改对$animate.enter$animate.leave的调用,在动画之后调用这些回调:

var callback = !oldValue && $scope.animatedIfEnterCallback ? $scope.animatedIfEnterCallback : (function() );
$animate.enter(clone, $element.parent(), $element, callback);

$animate.leave(block.clone, ($scope.animatedIfLeaveCallback || (function() )));

在初始加载指令时不调用回调的回车有点复杂。由于scope 参数,该指令创建了一个隔离范围,然后在转入内容时使用该范围。因此,需要进行的另一项更改是从指令的$parent 范围创建并使用一个子范围:行

 childScope = $scope.$new();

必须改为

 childScope = $scope.$parent.$new();

您可以see the full source of the modified ngIf directive in this Plunker。这只是经过非常简短的测试。

可能有一种更简单的方法来做到这一点,也许不是完全重新创建 ngIf 指令,而是使用模板创建一个指令,该模板使用原始 ngIf 和一些包装器 div,例如

template: '<div><div ng-if="localVariable"><div ng-transclude></div></div></div>'

【讨论】:

谢谢!!但是,您的动画-if 不适用于动画-if 内的数据绑定。看到这个forked plunker 你说得对:我已经编辑了帖子和指向允许数据绑定到原始范围的 Plunker 的链接。 仅供参考,您可以使用 angular.noop 代替 (function() )。为您节省 3 个字符 :) @MichalCharemza 按照您的回答,我似乎遇到了$scope.$apply 未被使用的问题。因此,例如,当我在回调内部更改控制器时,视图不会改变。我目前在回调中使用 $scope.$apply(function() ctrl.value = true;); 之类的结构来解决这个问题。 我已更新 plunker 以支持控制器更改,使用 childScope.$apply 我不确定脚本是否完全正常,但提供它作为解决方案的建议。

以上是关于AngularJS css 动画 + 完成回调的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS - 动画回调/序列

AngularJS动画卡片翻转

CSS3 动画完成时是不是有回调?

回调:动画完成:在 .promise().done() 之后调用

CSS 动画延迟和播放状态行为

html 一次完成回调的多个动画