it-swarm.com.de

Schieben Sie den Effekt mit ng-show und ng-animieren nach oben/unten

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.

73
Tony Lâmpada

Ich habe eine Angular-Direktive geschrieben, die slideToggle() ohne jQuery macht.

https://github.com/EricWVGG/AngularSlideables

84
Eric_WVGG

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!

40
elthrasher

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 )

17
Amit Portnoy

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

15
Luca

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

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.

5
steampowered

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.

4
Andrew Joslin

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