CSS 使用 ng-show 和 ng-animate 向上/向下滑动效果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16677304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Slide up/down effect with ng-show and ng-animate
提问by Tony Lampada
I'm trying to use ng-animate
to get a behavior similar to JQuery's slideUp()
and slideDown()
. Only I'd rather use ng-show
我试图用来ng-animate
获得类似于 JQueryslideUp()
和slideDown()
. 只有我宁愿使用ng-show
I'm looking at the ng-animate tutorial here - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html,
我在这里看 ng-animate 教程 - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html,
and I can reproduce the fade in/out effect in the example provided.
我可以在提供的示例中重现淡入/淡出效果。
How could I change the css to get slide up/down behaviour? Also, if possible, it's better that the css doesn't know about the component height in pixels. That way I can reuse the css for different elements.
如何更改 css 以获得向上/向下滑动的行为?此外,如果可能,最好让 css 不知道组件高度(以像素为单位)。这样我就可以为不同的元素重用 css。
回答by Eric_WVGG
I've written an Angular directive that does slideToggle()
without jQuery.
我写了一个slideToggle()
没有 jQuery的 Angular 指令。
回答by elthrasher
This is actually pretty easy to do. All you have to do is change the css.
这实际上很容易做到。你所要做的就是改变css。
Here's a fiddle with a very simple fade animation: http://jsfiddle.net/elthrasher/sNpjH/
这是一个非常简单的淡入淡出动画的小提琴:http: //jsfiddle.net/elthrasher/sNpjH/
To make it into a sliding animation, I first had to put my element in a box (that's the slide-container), then I added another element to replace the one that was leaving, just because I thought it would look nice. Take it out and the example will still work.
为了使其成为滑动动画,我首先必须将我的元素放在一个盒子中(即幻灯片容器),然后我添加了另一个元素来替换即将离开的元素,只是因为我认为它看起来不错。把它拿出来,这个例子仍然有效。
I changed the animation css from 'fade' to 'slide' but please note that these are the names I gave it. I could have written slide animation css named 'fade' or anything else for that matter.
我将动画 css 从“淡入淡出”更改为“幻灯片”,但请注意,这些是我给它起的名字。我本可以编写名为“fade”的幻灯片动画 css 或其他任何内容。
The important part is what's in the css. Here's the original 'fade' css:
重要的部分是 css 中的内容。这是原始的“淡入淡出”css:
.fade-hide, .fade-show {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.fade-hide {
opacity:1;
}
.fade-hide.fade-hide-active {
opacity:0;
}
.fade-show {
opacity:0;
}
.fade-show.fade-show-active {
opacity:1;
}
This code changes the opacity of the element from 0 (completely transparent) to 1 (completely opaque) and back again. The solution is to leave opacity alone and instead change the top (or left, if you want to move left-right).
此代码将元素的不透明度从 0(完全透明)更改为 1(完全不透明),然后再返回。解决方案是保持不透明度,而是更改顶部(或左侧,如果您想左右移动)。
.slide-hide, .slide-show {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
}
.slide-hide {
position: relative;
top: 0;
}
.slide-hide.slide-hide-active {
position: absolute;
top: -100px;
}
.slide-show {
position: absolute;
top: 100px;
}
.slide-show.slide-show-active {
position: relative;
top: 0px;
}
I'm also changing from relative to absolute positioning so only one of the elements takes up space in the container at a time.
我也将相对定位更改为绝对定位,因此一次只有一个元素占用容器中的空间。
Here's the finished product: http://jsfiddle.net/elthrasher/Uz2Dk/. Hope this helps!
这是成品:http: //jsfiddle.net/elthrasher/Uz2Dk/。希望这可以帮助!
回答by Amit Portnoy
update for Angular 1.2+(v1.2.6 at the time of this post):
Angular 1.2+ 的更新(本文发布时为 v1.2.6):
.stuff-to-show {
position: relative;
height: 100px;
-webkit-transition: top linear 1.5s;
transition: top linear 1.5s;
top: 0;
}
.stuff-to-show.ng-hide {
top: -100px;
}
.stuff-to-show.ng-hide-add,
.stuff-to-show.ng-hide-remove {
display: block!important;
}
(plunker)
(笨蛋)
回答by Luca
This can actuallybe done in CSS and very minimal JS just by adding a CSS class (don't set styles directly in JS!) with e.g. a ng-click
event. The principle is that one can't animate height: 0;
to height: auto;
but this can be tricked by animating the max-height
property. The container will expand to it's "auto-height" value when .foo-open
is set - no need for fixed height or positioning.
这实际上可以在 CSS 和非常小的 JS 中完成,只需添加一个 CSS 类(不要直接在 JS 中设置样式!),例如一个ng-click
事件。原则是不能设置动画height: 0;
,height: auto;
但是可以通过对max-height
属性设置动画来欺骗。设置时,容器将扩展到它的“自动高度”值.foo-open
- 不需要固定高度或定位。
.foo {
max-height: 0;
}
.foo--open {
max-height: 1000px; /* some arbitrary big value */
transition: ...
}
see this fiddle by the excellent Lea Verou
As a concern raised in the comments, note that while this animation works perfectly with linear easing, any exponential easing will produce a behaviour different from what could be expected - due to the fact that the animated property is max-height
and not height
itself; specifically, only the height
fraction of the easing curve of max-height
will be displayed.
作为评论中提出的一个问题,请注意,虽然此动画与线性缓动完美配合,但任何指数缓动都会产生与预期不同的行为 - 由于动画属性是max-height
而不是height
本身;具体来说,只会显示height
缓动曲线的一部分max-height
。
回答by steampowered
I ended up abandoning the code for my other answerto this question and going with this answer instead.
我最终放弃了我对这个问题的另一个答案的代码,而是选择了这个答案。
I believe the best way to do this is to not use ng-show
and ng-animate
at all.
我相信最好的方法是不使用ng-show
和根本不使用ng-animate
。
/* Executes jQuery slideDown and slideUp based on value of toggle-slidedown
attribute. Set duration using slidedown-duration attribute. Add the
toggle-required attribute to all contained form controls which are
input, select, or textarea. Defaults to hidden (up) if not specified
in slidedown-init attribute. */
fboApp.directive('toggleSlidedown', function(){
return {
restrict: 'A',
link: function (scope, elem, attrs, ctrl) {
if ('down' == attrs.slidedownInit){
elem.css('display', '');
} else {
elem.css('display', 'none');
}
scope.$watch(attrs.toggleSlidedown, function (val) {
var duration = _.isUndefined(attrs.slidedownDuration) ? 150 : attrs.slidedownDuration;
if (val) {
elem.slideDown(duration);
} else {
elem.slideUp(duration);
}
});
}
}
});
回答by steampowered
This class-based javascript animation works in AngularJS 1.2 (and 1.4 tested)
这个基于类的 javascript 动画适用于 AngularJS 1.2(和 1.4 测试)
Edit: I ended up abandoning this code and went a completely different direction. I like my other answer much better. This answer will give you some problems in certain situations.
编辑:我最终放弃了这段代码,走向了一个完全不同的方向。我更喜欢我的另一个答案。这个答案会在某些情况下给你带来一些问题。
myApp.animation('.ng-show-toggle-slidedown', function(){
return {
beforeAddClass : function(element, className, done){
if (className == 'ng-hide'){
$(element).slideUp({duration: 400}, done);
} else {done();}
},
beforeRemoveClass : function(element, className, done){
if (className == 'ng-hide'){
$(element).css({display:'none'});
$(element).slideDown({duration: 400}, done);
} else {done();}
}
}
});
});
Simply add the .ng-hide-toggle-slidedown
class to the container element, and the jQuery slide down behavior will be implemented based on the ng-hide class.
只需将该.ng-hide-toggle-slidedown
类添加到容器元素中,jQuery 向下滑动的行为就会基于 ng-hide 类来实现。
You must include the $(element).css({display:'none'})
line in the beforeRemoveClass
method because jQuery will not execute a slideDown unless the element is in a state of display: none
prior to starting the jQuery animation. AngularJS uses the CSS
您必须$(element).css({display:'none'})
在beforeRemoveClass
方法中包含该行,因为除非元素display: none
处于 jQuery 动画开始之前的状态,否则 jQuery 不会执行 slideDown 。AngularJS 使用 CSS
.ng-hide:not(.ng-hide-animate) {
display: none !important;
}
to hide the element. jQuery is not aware of this state, and jQuery will need the display:none
prior to the first slide down animation.
隐藏元素。jQuery 不知道这种状态,并且 jQuery 将需要display:none
在第一个向下滑动动画之前。
The AngularJS animation will add the .ng-hide-animate
and .ng-animate
classes while the animation is occuring.
AngularJS 动画将在动画发生时添加.ng-hide-animate
和.ng-animate
类。
回答by Andrew Joslin
You should use Javascript animations for this - it is not possible in pure CSS, because you can't know the height of any element. Follow the instructions it has for you about javascript animation implementation, and copy slideUp and slideDown from jQuery's source.
您应该为此使用 Javascript 动画 - 这在纯 CSS 中是不可能的,因为您无法知道任何元素的高度。按照它为您提供的有关 javascript 动画实现的说明,并从 jQuery 的源代码中复制 slideUp 和 slideDown。
回答by phil294
What's wrong with actually using ng-animate
for ng-show
as you mentioned?
正如你提到的,实际使用ng-animate
for有什么问题ng-show
?
<script src="lib/angulr.js"></script>
<script src="lib/angulr_animate.js"></script>
<script>
var app=angular.module('ang_app', ['ngAnimate']);
app.controller('ang_control01_main', function($scope) {
});
</script>
<style>
#myDiv {
transition: .5s;
background-color: lightblue;
height: 100px;
}
#myDiv.ng-hide {
height: 0;
}
</style>
<body ng-app="ang_app" ng-controller="ang_control01_main">
<input type="checkbox" ng-model="myCheck">
<div id="myDiv" ng-show="myCheck"></div>
</body>