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

Ton*_*ada 74 css css3 angularjs

我试图用ng-animate得到类似JQuery的行为slideUp()slideDown().只有我宁愿使用ng-show

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

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

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

Eri*_*VGG 87

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

https://github.com/EricWVGG/AngularSlideables

  • 我知道我们已经把它弄死了,但我喜欢将变量的可见性联系起来.此外,此解决方案不允许嵌入式滑块.我创造了一个兼具两者的小提琴:http://jsfiddle.net/rh7z7w0a/2/ (7认同)
  • @BastienSander Angular提供了一些Jquery方法的子集,如果在包含Angular,api文档之前不包含jquery:https://docs.angularjs.org/api/ng/function/angular.element .css和.bind在那里提供(用于"元素"变量).缓动和持续时间属性未在元素上使用,因此它们不引用同名的Jquery方法,而是在HTML属性(attrs对象)上传递的属性. (3认同)
  • 我见过的最简单的"手风琴"式滑盖!谢谢!我们对它进行了一些修改以删除我们认为不必要的ID和类内容,因为我们可以找到没有ID的元素:http://plnkr.co/edit/11NIZqB3G3KYKI0OChGA?p = preview (2认同)

小智 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;
}
Run Code Online (Sandbox Code Playgroud)

此代码将元素的不透明度从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;
}
Run Code Online (Sandbox Code Playgroud)

我也从相对位置变为绝对位置,因此每次只有一个元素占用容器中的空间.

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

  • 这种行为有点奇怪.有时文本从顶部出现,有时从底部出现. (2认同)

Ami*_*noy 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;
}
Run Code Online (Sandbox Code Playgroud)

(plunker)

  • 不要用css为顶部位置制作动画,它非常慢并占用大量内存.请改用翻译. (16认同)

Luc*_*uca 16

实际上可以在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: ...
}
Run Code Online (Sandbox Code Playgroud)

看到优秀的Lea Verou这个小提琴

作为评论中提出的一个问题,请注意虽然此动画与线性缓动完美配合,但任何指数缓动都会产生与预期不同的行为 - 由于动画属性本身max-height而非height本身; 具体而言,仅显示height缓和曲线的一部分max-height.

  • 这很糟糕,因为动画速度会根据"max-height"而变化. (3认同)

ste*_*red 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);
                }
            });
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

  • @tanguy_k我认为可能有办法纠正第一个答案,可能两种方法都是有效的.我想我希望有人会批评我的第一个答案并告诉我为什么它偶尔会失败.我认为这个问题可能有多个同样好的答案. (2认同)

ste*_*red 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();}
    }
}
Run Code Online (Sandbox Code Playgroud)

});

只需将.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;
}
Run Code Online (Sandbox Code Playgroud)

隐藏元素 jQuery不知道这种状态,jQuery将需要display:none在第一次下滑动画之前.

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