您可以使用.animation 定义基于 Javascript 的动画。例如,您定义为addClass 和removeClass 的值的函数
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
当 Angular 检测到您正在通过以下方法之一从元素中添加或删除类时调用:
-
{{ }} 在模板中插入。例如。 <span class="{{shouldFade ? 'fade' : ''}}">....
- 在模板中使用
ng-class。例如。 <span ng-class="{fade: shouldFade}">...
- 在指令中使用
$animate 服务。例如。 $animate.addClass(element, 'fade') 或 $animate.removeClass(element, 'fade')
什么是类名?是我想在淡入/淡出时申请的课程吗?我期待的课程?
在本例中为fade。诚然,这有点奇怪,因为在示例中已经很清楚这是所涉及的类名。但是,如果在同一个摘要循环中您将多个类添加到同一个元素,那么它们的连接将作为此字符串传递。
doneFn 是什么意思?我假设它是动画完成后运行的函数?里面有什么?
这是一个你在你定义的任何Javascript动画完成后调用的函数。例如,定义一个什么都不做的动画:
addClass: function(element, className, doneFn) {
doneFn();
},
调用它告诉 Angular 动画已经完成。除其他外,这将从元素中删除 ng-animate 类。
如果我已经有 doneFn,那么我应该在 addClass 和 removeClass 函数中做什么?
您在它们中放入一些代码,可能使用超时或 3rd 方库,以某种方式更改元素。完成后,您致电doneFn。例如,1 步不透明度“动画”:
addClass: function(element, className, doneFn) {
element.css('opacity', 0.5);
setTimeout(function() {
doneFn();
}, 1000);
},
我想直接使用 Angular 的 ngAnimate 模块,使用 CSS 或 JS 生成一个工作动画。
这与上面的答案没有太大关系!如果我在做一个真实案例,我强烈怀疑我会绝对定位元素,因为至少其他任何(我能想到的)都有点过于复杂。
但是,如果您确实想使用 ngAnimate 链接动画,一种可能的方法是使用 $animate.addClass 和 $animate.removeClass 在完成时返回一个承诺这一事实。为了链接到隐藏元素时返回的此类承诺的末尾,必须从某种中心位置调用它,并跟踪哪个元素可见、隐藏和显示。
这样做的一种方法是使用 2 个自定义指令。将在每个元素上显示和隐藏,可以非常像ngShow 使用。另一个是父指令,它允许在任何时候只允许一个元素可见,并在添加ng-hide 之后链式删除ng-hide 类(和相关动画)。指令必须进行通信,可以称为 ngShowUnique 和 ngShowUniqueController 之类的名称,如下例所示。
<div ng-show-unique-controller>
<h1 class="fade" ng-repeat="child in parent.children" ng-show-unique="parent.activeChild == child">@{{child.title}}</h1>
</div>
它们可以如下实现。
app.directive('ngShowUniqueController', function($q, $animate) {
return {
controller: function($scope, $element) {
var elements = [];
var expressions = [];
var watchers = [];
var unregisterWatchers = null;
var visibleElement = null;
function registerWatchers() {
unregisterWatchers = $scope.$watchGroup(expressions, function(vals) {
var newCurrentIndex = vals.indexOf(true);
var addPromise;
if (visibleElement) {
// Set a fixed height, as there is a brief interval between
// removal of this class and addition of another
$element.css('height', $element[0].getBoundingClientRect().height + 'px');
addPromise = $animate.addClass(visibleElement, 'ng-hide');
} else {
addPromise = $q.when();
}
visibleElement = elements[newCurrentIndex] || null;
if (!visibleElement) return;
addPromise.then(function() {
if (visibleElement) {
$animate.removeClass(visibleElement, 'ng-hide').then(function() {
$element.css('height', '');
});
}
})
});
}
this.register = function(element, expression) {
if (unregisterWatchers) unregisterWatchers();
elements.push(element[0]);
expressions.push(expression);
registerWatchers();
// Hide elements initially
$animate.addClass(element, 'ng-hide');
};
this.unregister = function(element) {
if (unregisterWatchers) unregisterWatchers();
var index = elements.indexOf(element[0]);
if (index > -1) {
elements.splice(index, 1);
expressions.splice(index, 1);
}
registerWatchers();
};
}
};
});
app.directive('ngShowUnique', function($animate) {
return {
require: '^ngShowUniqueController',
link: function(scope, element, attrs, ngShowUniqueController) {
ngShowUniqueController.register(element, function() {
return scope.$eval(attrs.ngShowUnique);
});
scope.$on('$destroy', function() {
ngShowUniqueController.unregister(element);
});
}
};
});
这可以在http://plnkr.co/edit/1eJUou4UaH6bnAN0nJn7?p=preview 看到。我不得不承认,这一切都有些古怪。