J'essaie d'utiliser ng-animate
pour obtenir un comportement similaire à slideUp()
et slideDown()
de JQuery. Seulement je préférerais utiliser ng-show
Je regarde le tutoriel ng-animate ici - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html ,
et je peux reproduire l'effet de fondu entrant/sortant dans l'exemple fourni.
Comment puis-je changer le fichier css pour obtenir un comportement de glissement vers le haut ou le bas? éléments.
J'ai écrit une directive angulaire qui slideToggle()
sans jQuery.
C'est en fait assez facile à faire. Tout ce que vous avez à faire est de changer le fichier css.
Voici un violon avec une animation de fondu très simple: http://jsfiddle.net/elthrasher/sNpjH/
Pour en faire une animation glissante, je devais d’abord placer mon élément dans une boîte (c’est le conteneur de diapositives), puis j’ai ajouté un autre élément pour remplacer celui qui partait, simplement parce que je pensais que cela aurait l’air agréable. Enlevez-le et l'exemple fonctionnera toujours.
J'ai changé le css d'animation de 'fade' à 'slide' mais veuillez noter que ce sont les noms que je lui ai donnés. J'aurais pu écrire une css d'animation de diapositives nommée 'fade' ou n'importe quoi d'autre à ce sujet.
La partie importante est ce qui est dans le css. Voici le css original 'fade':
.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;
}
Ce code modifie l'opacité de l'élément de 0 (complètement transparent) à 1 (complètement opaque) et inversement. La solution est de laisser l'opacité et de changer le sommet (ou la gauche si vous souhaitez vous déplacer de gauche à droite).
.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;
}
Je passe également du positionnement relatif au positionnement absolu, de sorte qu'un seul des éléments occupe de l'espace dans le conteneur à la fois.
Voici le produit fini: http://jsfiddle.net/elthrasher/Uz2Dk/ . J'espère que cela t'aides!
mise à jour pour Angular 1.2+ (v1.2.6 au moment de cet article):
.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 )
Cela peut réellement être fait en CSS et en JS très minimal en ajoutant simplement une classe CSS (ne définissez pas de styles directement dans JS!) Avec par exemple. un ng-click
event. Le principe est qu'il est impossible d'animer height: 0;
en height: auto;
, mais cela peut être trompé en animant la propriété max-height
. Le conteneur étendra sa valeur "auto-height" lorsque .foo-open
est défini - aucun besoin de hauteur ou de positionnement fixes.
.foo {
max-height: 0;
}
.foo--open {
max-height: 1000px; /* some arbitrary big value */
transition: ...
}
voir ce violon de l'excellente Lea Verou
En tant que préoccupation soulevée dans les commentaires, notez que, si cette animation fonctionne parfaitement avec l’assouplissement linéaire, tout assouplissement exponentiel produira un comportement différent de ce à quoi on pouvait s’attendre, car la propriété animée est max-height
et non pas height
. spécifiquement, seule la fraction height
de la courbe d’assouplissement de max-height
sera affichée.
J'ai fini par abandonner le code pour ma autre réponse à cette question et aller plutôt avec cette réponse.
Je crois que la meilleure façon de faire est de ne pas utiliser ng-show
et ng-animate
du tout.
/* 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);
}
});
}
}
});
Cette animation javascript basée sur les classes fonctionne dans AngularJS 1.2 (et testé 1.4)
Edit: J'ai fini par abandonner ce code et je suis allé dans une direction complètement différente. J'aime mon autre réponse est beaucoup mieux }. Cette réponse vous donnera des problèmes dans certaines 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();}
}
}
});
Ajoutez simplement la classe .ng-hide-toggle-slidedown
à l'élément conteneur et le comportement de glisser-déposer de jQuery sera implémenté en fonction de la classe ng-hide.
Vous devez inclure la ligne $(element).css({display:'none'})
dans la méthode beforeRemoveClass
car jQuery n'exécutera pas de slideDown sauf si l'élément est dans l'état display: none
avant de lancer l'animation jQuery. AngularJS utilise le CSS
.ng-hide:not(.ng-hide-animate) {
display: none !important;
}
cacher l'élément. jQuery n'est pas au courant de cet état et jQuery aura besoin du display:none
avant la première animation.
L'animation AngularJS ajoutera les classes .ng-hide-animate
et .ng-animate
pendant le déroulement de l'animation.
Vous devez utiliser des animations Javascript pour cela - ce n'est pas possible en CSS pur, car vous ne pouvez connaître la hauteur d'aucun élément. Suivez les instructions qu'il a pour vous concernant la mise en œuvre de l'animation javascript et copiez slideUp et slideDown à partir de la source de jQuery.
Qu'est-ce qui ne va pas avec l'utilisation de ng-animate
pour ng-show
comme vous l'avez mentionné?
<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>