Javascript Don';在ng hide CSS转换完成之前是否显示元素?
这个问题很简单,但我在实现上遇到了麻烦。如果我有以下DOM设置:Javascript Don';在ng hide CSS转换完成之前是否显示元素?,javascript,angularjs,animation,Javascript,Angularjs,Animation,这个问题很简单,但我在实现上遇到了麻烦。如果我有以下DOM设置: <h1 class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild== child ">@{{ child.title }}</h1> 但是,这最终会产生: 本质上,我想链接我的动画。我已经试着阅读了,但是我在语法上遇到了问题,无法达到我想要的效果 我见过有棱角的文档有这样的东西: app.animation
<h1 class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild== child ">@{{ child.title }}</h1>
但是,这最终会产生:
本质上,我想链接我的动画。我已经试着阅读了,但是我在语法上遇到了问题,无法达到我想要的效果
我见过有棱角的文档有这样的东西:
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
- 什么是
?淡入淡出时,我想申请的是哪门课?我期待的课程李>className
- 什么是
?我假设它是一个在动画完成后运行的函数?里面有什么doneFn
- 如果我已经有了一个
,那么在doneFn
和addClass
函数中该怎么做removeClass
我想直接使用Angular的ngAnimate模块生成一个工作动画,使用CSS或JS。我怎样才能做到这一点呢?为什么对每个标题使用单独的
。您可以使用单个
标记来显示标题
我已经为你的问题创建了一个演示,我已经成功地完成了你的要求
已更新
注意,代码被编辑为使用ngAnimate
模块。当您使用ngAnimate
模块时,当您隐藏一个元素时,它将创建一个类.ng hide
这是你的应用程序的控制器
app2.controller("testController", ["$scope", "$timeout", function ($scope, $timeout) {
$scope.heading = {};
$scope.heading.show = true;
$scope.parent = {};
$scope.parent.children = ["A", "B", "C", "D"];
$scope.parent.activeChild = "A";
$scope.changeHeading = function (child) {
$timeout(function () {
$scope.parent.activeChild = child;
$scope.heading.show = true;
}, 1000);
}
}]);
你的html页面应该是这样的
<div ng-controller="testController">
<h1 class="myAnimateClass" ng-show="heading.show" ng-class="{fadeIn : heading.fadeInModel==true, fadeOut : heading.fadeOutModel}"> {{parent.activeChild}} </h1>
<p ng-repeat="child in parent.children" ng-click="heading.show = false;changeHeading(child)">{{child}}</p>
</div>
解释
为了满足您的需求,我在angularJS中使用了ng类
和$timeout
您可以看到,我只有一个
标签来显示您的标题。当我更改标题时,我只是更改它的绑定属性$scope.parent.activeChild
我使用了两个作用域变量$scope.heading.fadeOutModel
和$scope.heading.fadeInModel
动态添加和删除类fadeIn
和fadeOut
当用户单击更改标题时,我已将类<代码>淡出添加到您的标题中。因此,这将显示淡出的动画。我还在app.js中启动了一个函数,changeHeading()
您可以看到,我强制角度传感器等待1000
毫秒以完成淡出动画。在此之后,它将把所选标题替换为新标题,并添加一个类fadeIn
。因此,它将启动淡入动画
希望这对你有帮助 根据选择显示特定元素的更具动画效果的方法是使用
ngSwitch
。此指令用于基于范围表达式有条件地交换模板上的DOM结构。这是一本书
HTML
<button ng-repeat="item in items" ng-click="parent.selection = item">{{ item }}</button>
<div class="animate-switch-container" ng-switch on="parent.selection">
<div class="animate-switch" ng-switch-when="foo">foo</div>
<div class="animate-switch" ng-switch-when="bar">bar</div>
</div>
<body ng-controller="MainCtrl">
<h1><span class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild == child ">@{{child.title}}</span></h1>
<button ng-repeat="child in parent.children" ng-click="parent.activeChild = child">{{ child.title }}</button>
</body>
CSS
.animate-switch-container {
position:relative;
height:40px;
overflow:hidden;
}
.animate-switch {
padding:10px;
}
.animate-switch.ng-animate {
transition:opacity 1s ease;
}
.animate-switch.ng-leave.ng-leave-active,
.animate-switch.ng-enter {
opacity: 0;
}
.animate-switch.ng-leave,
.animate-switch.ng-enter.ng-enter-active {
opacity: 1;
}
.fade {
opacity: 1;
position: relative;
}
.fade.ng-hide-add {
transition:opacity 1s ease;
position: absolute;
}
.fade.ng-hide-remove {
transition:opacity 1s ease 1s;
position: absolute;
}
.fade.ng-hide-add {
opacity:1;
}
.fade.ng-hide-add.ng-hide-add-active {
opacity:0;
}
.fade.ng-hide-remove {
opacity:0;
}
.fade.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
这不是链接,而是直接使用Angular的ngAnimate模块的工作动画。这里还有一个。您可以使用
.animation
定义基于Javascript的动画。例如,您定义为addClass
和removeClass
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
当Angular检测到您正在从以下方法之一的元素中添加或删除类时,将调用:
在模板中插入。例如,{{}
…
- 在模板中使用
。例如,ng类
…
- 在指令中使用
服务。例如,$animate
$animate.addClass(元素“淡入”)或
$animate.removeClass(元素“淡入”)
fade
。不可否认,这有点奇怪,因为在示例中已经很清楚这是所涉及的类名。但是,如果在同一个摘要循环中,您将多个类添加到同一个元素中,那么它们的串联将作为此字符串传递
doneFn的本意是什么?我假设它是一个在动画完成后运行的函数?里面有什么
这是一个函数,您可以在定义的Javascript动画完成后调用它。例如,要定义不作为全部的动画,请执行以下操作:
addClass: function(element, className, doneFn) {
doneFn();
},
调用它会告诉Angular动画已完成。这将从元素中删除ng animate
类
如果我已经有了一个doneFn,那么在addClass和removeClass函数中该怎么做
您可以在其中添加一些代码,可能使用超时或第三方库,以某种方式更改元素。完成后,调用doneFn
。例如,一步不透明度“动画”:
我想直接使用Angular的ngAnimate模块生成一个工作动画,使用CSS或JS
这与上面的答案没有多大关系!如果我在做一个真实的案例,我强烈怀疑我会绝对地定位元素,因为至少我能想到的其他任何东西都有点过于复杂
但是,如果确实希望使用ngAnimate链接动画,一种可能的方法是使用$animate.addClass
和$animate.removeClass
在完成时返回承诺。为了链接到隐藏元素时返回的承诺的末尾,必须从某种中心位置调用它,并跟踪哪个元素是可见的、隐藏的和显示的
一种方法是使用2个自定义指令。每个元素上都会有一个元素用于显示和隐藏,这非常类似于ngShow
。另一个是父指令,它在任何时候都只允许一个元素可见,并且在添加ng hide
后链删除ng hide
类(和相关动画)。指令必须传达,co
addClass: function(element, className, doneFn) {
doneFn();
},
addClass: function(element, className, doneFn) {
element.css('opacity', 0.5);
setTimeout(function() {
doneFn();
}, 1000);
},
<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);
});
}
};
});
.fade {
opacity: 1;
position: relative;
}
.fade.ng-hide-add {
transition:opacity 1s ease;
position: absolute;
}
.fade.ng-hide-remove {
transition:opacity 1s ease 1s;
position: absolute;
}
.fade.ng-hide-add {
opacity:1;
}
.fade.ng-hide-add.ng-hide-add-active {
opacity:0;
}
.fade.ng-hide-remove {
opacity:0;
}
.fade.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
<body ng-controller="MainCtrl">
<h1><span class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild == child ">@{{child.title}}</span></h1>
<button ng-repeat="child in parent.children" ng-click="parent.activeChild = child">{{ child.title }}</button>
</body>
element.addEventListener('transitionend', callback, false);