Ich versuche, ng-animate
zu verwenden, um ein ähnliches Verhalten wie slideUp()
und slideDown()
von JQuery zu erhalten. Nur ich würde lieber ng-show
verwenden
Ich schaue mir das ng-animierte Tutorial hier an - http://www.yearofmoo.com/2014/04/animation-in-angularjs.html ,
und ich kann den Fade-In/Out-Effekt im angegebenen Beispiel reproduzieren.
Wie kann ich die CSS ändern, um das Verhalten nach oben/unten zu verschieben? Außerdem ist es besser, wenn die CSS die Komponentenhöhe in Pixeln nicht kennt. Auf diese Weise kann ich die CSS für andere Zwecke wiederverwenden Elemente.
Ich habe eine Angular-Direktive geschrieben, die slideToggle()
ohne jQuery macht.
Das ist eigentlich ziemlich einfach. Sie müssen lediglich die CSS ändern.
Hier ist eine Geige mit einer sehr einfachen Überblend-Animation: http://jsfiddle.net/elthrasher/sNpjH/
Um es in eine Sliding-Animation zu verwandeln, musste ich mein Element zuerst in eine Box legen (das ist der Slide-Container), dann habe ich ein anderes Element hinzugefügt, um das zu ersetzen, das gerade verlassen wurde, nur weil ich dachte, es würde schön aussehen. Nehmen Sie es heraus und das Beispiel wird noch funktionieren.
Ich habe die Animation css von 'fade' in 'slide' geändert, aber bitte beachten Sie, dass dies die Namen sind, die ich ihnen gegeben habe. Ich hätte eine Folienanimation css mit dem Namen "fade" oder irgendetwas anderes schreiben können.
Der wichtige Teil ist, was in der CSS ist. Hier ist das Original 'fade' 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;
}
Dieser Code ändert die Deckkraft des Elements von 0 (vollständig transparent) in 1 (vollständig undurchsichtig) und wieder zurück. Die Lösung besteht darin, die Deckkraft in Ruhe zu lassen und stattdessen die Oberseite zu ändern (oder nach links, wenn Sie sich von links nach rechts bewegen möchten).
.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;
}
Ich wechsle auch von einer relativen zur absoluten Positionierung, sodass jeweils nur eines der Elemente Platz im Container beansprucht.
Hier ist das fertige Produkt: http://jsfiddle.net/elthrasher/Uz2Dk/ . Hoffe das hilft!
update für Angular 1.2+ (v1.2.6 zum Zeitpunkt dieses Beitrags):
.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 )
Dies kann eigentlich in CSS und sehr minimalem JS erfolgen, indem Sie einfach eine CSS-Klasse hinzufügen (Stile nicht direkt in JS setzen!), Z. ein ng-click
event. Das Prinzip ist, dass man height: 0;
nicht zu height: auto;
animieren kann, aber dies kann durch Animieren der max-height
-Eigenschaft ausgetrickst werden. Der Container wird auf den Wert "auto-height" erweitert, wenn .foo-open
eingestellt ist. Eine feste Höhe oder Positionierung ist nicht erforderlich.
.foo {
max-height: 0;
}
.foo--open {
max-height: 1000px; /* some arbitrary big value */
transition: ...
}
sehen diese Geige von der ausgezeichneten Lea Verou
Bedenken Sie in den Kommentaren die Besorgnis, dass diese Animation zwar perfekt mit linearer Lockerung funktioniert, jede exponentielle Lockerung jedoch zu einem anderen Verhalten als erwartet führt, da die animierte Eigenschaft max-height
und nicht height
selbst ist. Insbesondere wird nur der height
-Anteil der Beschleunigungskurve von max-height
angezeigt.
Am Ende habe ich den Code für meine andere Antwort auf diese Frage aufgegeben und bin stattdessen mit dieser Antwort gegangen.
Ich glaube, der beste Weg, dies zu tun, ist, ng-show
und ng-animate
überhaupt nicht zu verwenden.
/* 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);
}
});
}
}
});
Diese klassenbasierte Javascript-Animation funktioniert in AngularJS 1.2 (und 1.4 wurde getestet).
Edit: Ich habe diesen Code aufgegeben und eine völlig andere Richtung eingeschlagen. Ich mag meine andere Antwort viel besser . Diese Antwort gibt Ihnen in bestimmten Situationen einige Probleme.
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();}
}
}
});
Fügen Sie einfach die .ng-hide-toggle-slidedown
-Klasse zum Container-Element hinzu, und das Verhalten der jQuery-Folie wird auf der Grundlage der Klasse ng-hide implementiert.
Sie müssen die Zeile $(element).css({display:'none'})
in die Methode beforeRemoveClass
einschließen, da jQuery vor dem Start der jQuery-Animation kein slideDown ausführt, es sei denn, das Element befindet sich im Zustand display: none
. AngularJS verwendet das CSS
.ng-hide:not(.ng-hide-animate) {
display: none !important;
}
das Element ausblenden. jQuery kennt diesen Status nicht und jQuery benötigt den display:none
vor der ersten Animation.
Die AngularJS-Animation fügt die .ng-hide-animate
- und .ng-animate
-Klassen hinzu, während die Animation stattfindet.
Sie sollten dazu Javascript-Animationen verwenden - in reinem CSS ist dies nicht möglich, da Sie die Höhe eines Elements nicht kennen können. Folgen Sie den Anweisungen, die Sie zur Javascript-Animationsimplementierung erhalten haben, und kopieren Sie slideUp und slideDown aus jQuery's Quelle.
Was ist daran falsch, ng-animate
für ng-show
zu verwenden, wie Sie erwähnt haben?
<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>