使用ng-show和ng-animate向上/向下滑动效果


74

我正在尝试使用ng-animate类似于JQueryslideUp()和的行为slideDown()。只有我宁愿使用ng-show

我在这里查看ng-animate教程-http: //www.yearofmoo.com/2013/04/animation-in-angularjs.html

我可以在提供的示例中再现淡入/淡出效果。

我如何更改CSS来获得向上/向下滑动的行为?另外,如果可能的话,最好让CSS不知道以像素为单位的组件高度。这样,我可以将CSS重用于不同的元素。


1
我认为您将无法进行ng-show处理动画。那不是它的预期用途。那就是ng-animate的目的。为什么要专门使用ng-show?
乔纳森·帕卢博

1
谢谢乔纳森。我想你错了。给定的示例确实做到了:ng-show和ng-animate的组合(请查看“ Animating ngShow&ngHide”)。无论如何,我想要的只是显示/隐藏div上下滑动的效果。
TonyLâmpada'13

我的错误,我没有使用ng-animate。看起来好像它们在彼此协同工作。
乔纳森·帕卢博

您可以尝试使用line-heightcss属性,范围是0到100%。有时是可行的...发布您的小提琴,以求我们能更好地帮助您。如果您找到执行此操作的好方法,请将其发送给我,然后将此示例放在我的网站上:AngularJS Ng-Animate
Bruno Croys Felthes

Answers:


87

我写了一个slideToggle()没有jQuery的Angular指令。

https://github.com/EricWVGG/AngularSlideables


1
这看起来就像我想要的。谢谢!
托尼·兰帕达(TonyLâmpada),

3
@BastienSander Angular提供了一些Jquery方法的子集,如果您在此处包含Angular的api文档之前不包括jquery:docs.angularjs.org/api/ng/function/angular.element .css和.bind在那里提供(用于“元素”变量)。easing和duration属性未在element上使用,因此它们没有引用同名的Jquery方法,而是在HTML属性(attrs对象)上传递的属性。
杰伊·克莱尔

2
我见过的最小的“手风琴”样式滑块!谢谢!我们对其进行了一些修改,以删除我们认为不必要的ID和类内容,因为我们可以找到没有ID的元素:plnkr.co/edit/11NIZqB3G3KYKI0OChGA?p=preview
Pylinux

1
id是必需的(如果您想下拉其他位置的元素),因此我进行了一些修改,修复了一些错误,现在它就像一种魅力。plnkr.co/edit/XdRjap3TPFEC9180yq9k?p=preview
Marcio

7
我知道我们已经为此付出了代价,但是我喜欢将可见性与变量联系在一起。另外,此解决方案不允许使用嵌入式滑块。我创建了一个小提琴,可同时实现这两者:jsfiddle.net/rh7z7w0a/2
jbodily

40

这实际上很容易做到。您所要做的就是更改CSS。

这是一个带有非常简单的淡入淡出动画的小提琴:http : //jsfiddle.net/elthrasher/sNpjH/

为了使其成为滑动动画,我首先必须将我的元素放在一个盒子(这是幻灯片容器)中,然后我添加了另一个元素来替换要离开的元素,只是因为我认为它看起来不错。删除它,该示例仍然有效。

我将动画CSS从“淡入淡出”更改为“幻灯片”,但请注意,这些是我给它命名的。我本来可以写一个名为“ 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;
}

此代码将元素的不透明度从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;
}

我也从相对位置更改为绝对位置,因此一次只有一个元素会占用容器中的空间。

这是成品:http : //jsfiddle.net/elthrasher/Uz2Dk/。希望这可以帮助!


这非常有帮助。我试图弄清楚为什么“隐藏”过渡在您的提琴演奏中如此突然,@ elthrasher
ericpeters0n 2014年

1
@ ericpeters0n-这是因为过渡行的末尾有0.5s。那是要花费的时间,在这种情况下是半秒。您可以将其设置为任何您喜欢的。尝试5s或10s。
elthrasher 2014年

2
这种行为有点奇怪。有时文本从顶部出现,有时从底部出现。
尼克·王

我知道这是一个旧答案,但是如果有人想尝试一下,我想澄清一下usingng-hide="hidden == false"是多余的,如果hidden变量已经是布尔值,那么根本就不需要运算符。
GMaiolo's

17

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;
}

矮人


16
不要使用CSS设置顶部动画,这非常慢并且会占用大量内存。请改用翻译。
Michael Tempest 2014年

1
也可用于Angular 1.4。经过测试,它就像一个魅力!
Flame_Phoenix

16

实际上,这可以通过添加CSS类(不要在JS中直接设置样式!)和ng-click事件来在CSS和最小的JS中完成。原理是不能设置动画height: 0;height: auto;但是可以通过给max-height属性设置动画来欺骗。设置后,容器将扩展到其“自动高度”值.foo-open-无需固定高度或位置。

.foo {
    max-height: 0;
}

.foo--open {
    max-height: 1000px; /* some arbitrary big value */
    transition: ...
}

观看Lea Verou的出色演奏

作为评论中的一个关注点,请注意,尽管该动画可以很好地与线性缓动一起使用,但是任何指数缓动都会产生与预期不同的行为-由于动画属性本身max-height而不是height其本身;具体来说,只会显示height缓和曲线的一部分max-height


3
不好的原因是动画速度会根据改变max-height
RushPL 2015年

为什么不好?如果您对动画速度有疑问,只需根据您的设置过渡时间即可max-height。这正是过渡应该如何工作的方式。这种方法实际上具有以下优点:无论height
Luca

1
@RushPL这是一个公平的解释-现在有意义。
卡2015年

1
我必须对这种方法进行投票。简单,以及使用ngAnimate框架。
windmaoo

1
这应该被标记为答案,因为我是在这里领导寻找作弊高度的方法:就像原始海报一样,汽车是
Erik Grosskurth'Aug

8

我最终放弃了该问题的其他答案的代码,而是继续使用此答案。

我认为,要做到这一点的最好办法是不使用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);
                }
            });
        }
    }
});

感谢您提供更新的解决方案。出于好奇(因为我没有发现ng-hide / ng-show附带任何特别的问题)...这种方法有什么问题?
zai chang 2015年

您应该已经修改了之前的答案,而不是创建一个新的答案(想象一下,如果每个人每次都想修改某项内容时都创建一个新答案,那么混乱……)
tanguy_k 2015年

2
@tanguy_k我认为可能有一种方法可以纠正第一个答案,并且可能两种方法都有效。我想我希望有人批评我的第一个答案,并告诉我为什么它有时会失败。我认为这个问题可能有多个同样好的答案。
2015年

1
编辑原始答案的问题是,如果发问者将其标记为“正确”,然后您进行了重要的修改……这似乎也是一个坏主意。
布雷特·格林

6

这种基于类的javascript动画可在AngularJS 1.2(和1.4测试)中使用

编辑:我最终放弃了这段代码,朝着完全不同的方向发展。我更喜欢其他答案。在某些情况下,此答案将给您带来一些问题。

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();}
    }
}

});

只需添加 .ng-hide-toggle-slidedown类到容器元素中,jQuery的下滑行为将基于ng-hide类实现。

您必须$(element).css({display:'none'})beforeRemoveClass方法中包括该行,因为除非元素在display: none开始jQuery动画之前处于,否则jQuery将不会执行slideDown 。AngularJS使用CSS

.ng-hide:not(.ng-hide-animate) {
    display: none !important;
}

隐藏元素。jQuery不了解这种状态,因此jQuery需要display:none先于第一个向下滑动动画。

动画发生时,AngularJS动画将添加.ng-hide-animate.ng-animate类。


当我无法获得其他答案对我来说很好时,这对我来说非常有效。投票!
zai chang 2015年

@zaichang我最终放弃了这段代码,转向了一个完全不同的方向。我更喜欢其他答案。在某些情况下,此答案将给您带来一些问题。
蒸汽动力

@steampowered不能使用ngIf。但是我也看到,即使您使用它,在某些情况下它也不起作用ngShow。例如,当我在通过UI-Bootstrap创建的模式中使用它时,它似乎不起作用。真奇怪 它什么时候对您失败?
2016年

display:none没什么用...使用ng-animate / ng-show和enter / leave函数以及jquery UI切换效果。在我添加display:none到元素之前,Nothign一直没有工作,谢谢!
布雷特·格林

3

您应该为此使用Javascript动画-在纯CSS中是不可能的,因为您不知道任何元素的高度。按照它为您提供的有关JavaScript动画实现的说明,并从jQuery的源代码中复制slideUp和slideDown。


0

正如您所提到的,实际使用ng-animatefor有什么问题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>

1
如果您可以在CSS中对高度进行硬编码,则可以使用此方法,但这通常是不可能的。
Waruyama
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.