Pregunta Deslice el efecto hacia arriba / abajo con ng-show y ng-animate


Estoy tratando de usar ng-animate para obtener un comportamiento similar al de JQuery slideUp() y slideDown(). Solo prefiero usar ng-show

Estoy viendo el tutorial ng-animate aquí - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html,

y puedo reproducir el efecto de entrada / salida de fundido en el ejemplo proporcionado.

¿Cómo podría cambiar el CSS para obtener el comportamiento de deslizamiento hacia arriba / abajo? Además, si es posible, es mejor que el CSS no conozca la altura del componente en píxeles. De esa forma puedo reutilizar el CSS para diferentes elementos.


73
2018-05-21 18:46


origen


Respuestas:


He escrito una directiva angular que hace slideToggle() sin jQuery.

https://github.com/EricWVGG/AngularSlideables


84
2017-11-01 21:51



Esto es realmente bastante fácil de hacer. Todo lo que tienes que hacer es cambiar el CSS.

Aquí hay un violín con una animación de desvanecimiento muy simple: http://jsfiddle.net/elthrasher/sNpjH/

Para convertirlo en una animación deslizante, primero tuve que poner mi elemento en una caja (ese es el contenedor deslizante), luego agregué otro elemento para reemplazar el que se estaba yendo, solo porque pensé que se vería bien. Sácalo y el ejemplo seguirá funcionando.

Cambié la animación css de 'fade' a 'slide', pero tenga en cuenta que estos son los nombres que le di. Podría haber escrito una animación de diapositivas css llamada 'fade' o cualquier otra cosa para el caso.

La parte importante es lo que hay en el CSS. Aquí está el css 'fade' original:

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

Este código cambia la opacidad del elemento de 0 (completamente transparente) a 1 (completamente opaco) y viceversa. La solución es dejar la opacidad solo y en su lugar cambiar la parte superior (o izquierda, si desea mover izquierda-derecha).

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

También estoy cambiando del posicionamiento relativo al absoluto, por lo que solo uno de los elementos ocupa espacio en el contenedor a la vez.

Aquí está el producto terminado: http://jsfiddle.net/elthrasher/Uz2Dk/. ¡Espero que esto ayude!


40
2018-06-03 12:41



actualización para Angular 1.2+ (v1.2.6 en el momento de esta publicación):

.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)


16
2017-12-21 17:14



Esto puede actualmente hacerse en CSS y JS muy mínimo simplemente agregando una clase de CSS (¡no configure estilos directamente en JS!) con, por ejemplo, un ng-clickevento. El principio es que uno no puede animar height: 0; a height: auto; pero esto puede ser engañado animando el max-height propiedad. El contenedor se expandirá a su valor de "altura automática" cuando .foo-open está configurado, no es necesario que la altura o el posicionamiento sea fijo.

.foo {
    max-height: 0;
}

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

ver este violín por la excelente Lea Verou

Como una preocupación planteada en los comentarios, tenga en cuenta que si bien esta animación funciona perfectamente con la aceleración lineal, cualquier relajación exponencial producirá un comportamiento diferente de lo que podría esperarse, debido al hecho de que la propiedad animada es max-height y no height sí mismo; específicamente, solo el height fracción de la curva de relajación de max-height será mostrado.


15
2018-03-11 18:15



Terminé abandonando el código para mi otra respuesta a esta pregunta y yendo con esta respuesta en su lugar.

Creo que la mejor manera de hacerlo es no usar ng-show y ng-animate en absoluto.

/* 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);
                }
            });
        }
    }
});

7
2017-08-20 19:05



Esta animación javascript basada en clase funciona en AngularJS 1.2 (y 1.4 probado)

Editar: Terminé abandonando este código y tomé una dirección completamente diferente. me gusta mi otra respuesta mucho mejor. Esta respuesta le dará algunos problemas en ciertas situaciones.

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

});

Simplemente agrega el .ng-hide-toggle-slidedown clase al elemento contenedor, y el comportamiento de deslizamiento jQuery se implementará en función de la clase ng-hide.

Debes incluir el $(element).css({display:'none'}) línea en el beforeRemoveClass método porque jQuery no ejecutará un slideDown a menos que el elemento esté en un estado de display: none antes de comenzar la animación jQuery. AngularJS usa el CSS

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

para ocultar el elemento jQuery no tiene conocimiento de este estado, y jQuery necesitará el display:none antes de la primera animación de deslizamiento hacia abajo.

La animación AngularJS agregará .ng-hide-animate y .ng-animate clases mientras la animación está ocurriendo.


5
2017-07-20 18:52



Deberías usar animaciones Javascript para esto, no es posible en CSS puro, porque no puedes conocer la altura de ningún elemento. Siga las instrucciones que tiene sobre la implementación de la animación de JavaScript y copie slideUp y slideDown de la fuente de jQuery.


4
2018-05-21 19:28



¿Qué hay de malo con el uso de realidad? ng-animate para ng-show ¿como lo mencionaste?

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

0
2018-04-01 15:38