2016-06-30 5 views
0

Dies ist eine stark vereinfachte Demo von ng-class Animation mit Übergang, die ich versuche zu erreichen.Warum funktioniert der auf der ng-Klasse basierende ng-animate-Übergang nicht?

Ich versuche, eine einfache Einblendung Animation zu erstellen, wenn ein Element ausgewählt ist.

Bei Auswahl eines Elements wird eine selected-Klasse mit der ng-class-Direktive hinzugefügt. Ich versuche, einen Übergang dazu hinzuzufügen, der dem documentation mit den Animationshakenklassen folgt, die durch ng-animate hinzugefügt werden.

Unten ist der Code, den ich bisher habe. Es setzt die opacity zu 0 zusammen mit der Übergangseigenschaft, und wenn die .selected-add-active Klasse hinzugefügt wird, soll es zu opacity übergehen 1. Aber es funktioniert nicht.

angular.module('demo', ['ngAnimate']) 
 
    .controller('demoCtrl', function($scope) { 
 
    $scope.selected = false; 
 
    $scope.selectToggle = function() { 
 
     $scope.selected = !$scope.selected; 
 
    }; 
 
    });
.item { 
 
    width: 50px; 
 
    height: 50px; 
 
    background: grey; 
 
} 
 
.item.selected { 
 
    background-color: dodgerblue; 
 
} 
 
.item.selected.selected-add { 
 
    transition: opacity 3s; 
 
    opacity: 0; 
 
} 
 
.item.selected.selected-add.selected-add-active { 
 
    opacity: 1; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.js"></script> 
 
<div ng-app="demo" ng-controller="demoCtrl"> 
 
    <div class="item" ng-class="{selected:selected}"></div> 
 
    <br> 
 
    <br> 
 
    <button ng-click="selectToggle();"> 
 
    {{selected? 'Unselect' : 'Select'}} 
 
    </button> 
 
</div>

Warum funktioniert mein Code nicht?

Antwort

3

Das Problem hier scheint die Reihenfolge zu sein, in der angular ng-animate die CSS-Klassen anwendet und wie der Browser DOM-Reflows optimiert.

ng-animate fügt zunächst die Klasse x-add hinzu, bevor die Klasse x hinzugefügt wird. Hier wird ein DOM-Reflow erzwungen (oder nachgeahmt), sodass der Browser den Anfangszustand für die Animation erkennt.

Aber da der Selektor für Anfangszustand CSS (.item.selected.selected-add) mit .selected Klasse verkettet ist, die noch nicht hinzugefügt wird, stimmt es überhaupt nicht überein und Browser ignoriert es.

Danach fügt ng-animate die selected Klasse hinzu, gefolgt von selected-add-active Klasse. An diesem Punkt der CSS-Selektor für den Ausgangszustand entspricht, aber diese Änderungen geschieht in der gleichen Reflow, daher wählt der Browser opacity von dem Selektor mit höchster Spezifität anzuwenden, die

.item.selected.selected-add.selected-add-active { 
    opacity: 1; 
} 

Jetzt in der, da keine tatsächliche Änderung ist Elements opacity erkannt wird, findet kein Übergang statt.


Um dies zu beheben, vermeiden Sie die Animation Haken Klassen von ng-animate mit der Klasse umgeschaltet werden hinzugefügt Verkettungs. Insbesondere die Klasse x-add, die vor den folgenden Klassen vom Browser erkannt werden soll, wird angewendet.

Im Folgenden finden Sie ein funktionierendes Beispiel:

angular.module('demo', ['ngAnimate']) 
 
    .controller('demoCtrl', function($scope) { 
 
    $scope.selected = false; 
 
    $scope.selectToggle = function() { 
 
     $scope.selected = !$scope.selected; 
 
    }; 
 
    });
.item { 
 
    width: 50px; 
 
    height: 50px; 
 
    background: grey; 
 
} 
 
.item.selected { 
 
    background-color: dodgerblue; 
 
} 
 
.item.selected-add { 
 
    transition: opacity 3s; 
 
    opacity: 0; 
 
} 
 
.item.selected-add.selected-add-active { 
 
    opacity: 1; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.js"></script> 
 
<div ng-app="demo" ng-controller="demoCtrl"> 
 
    <div class="item" ng-class="{selected:selected}"></div> 
 
    <br> 
 
    <br> 
 
    <button ng-click="selectToggle();"> 
 
    {{selected? 'Unselect' : 'Select'}} 
 
    </button> 
 
</div>

Verwandte Themen