2016-06-30 1 views
0

Ceci est une démo très simplifiée de l'animation ng-class en utilisant la transition que j'essaie d'atteindre. J'essaye de créer une animation de fondu simple quand un article est sélectionné.Pourquoi la transition ng-animate ng-class ne fonctionne-t-elle pas?

La sélection d'un élément ajoutera une classe selected à l'aide de la directive ng-class. J'essaye d'ajouter une transition après le documentation avec les classes de hook d'animation ajoutées par ng-animate.

Voici le code que j'ai jusqu'ici. Il définit le opacity à 0 avec la propriété de transition, et lorsque la classe .selected-add-active est ajoutée, elle est supposée passer à opacity 1. Mais cela ne fonctionne pas.

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>

Pourquoi mon code de travail?

Répondre

3

Le problème ici semble être l'ordre dans lequel angulaire ng-animate applique les classes CSS et comment le navigateur optimise les flux DOM. Initialement ajoute la classe x-add avant d'ajouter réellement la classe x. C'est là qu'il force (ou simule) un refusion DOM pour que le navigateur détecte l'état initial de l'animation.

Mais puisque le sélecteur pour CSS de l'état initial (.item.selected.selected-add) est chaîné avec la classe .selected qui n'est pas encore ajoutée, il ne correspond à rien et le navigateur l'ignore. Après cela, ng-animate ajoute la classe selected suivie par la classe selected-add-active. A ce stade, le sélecteur CSS pour l'état initial correspond, mais ces changements se passe dans le même refusion, d'où le navigateur choisit d'appliquer opacity du sélecteur avec une spécificité plus élevée qui est

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

Maintenant, puisque aucun changement réel dans la opacity de l'élément est détecté, aucune transition n'a lieu.


Pour résoudre ce problème, évitez enchaînant les classes de crochet d'animation ajoutée par ng-animate avec la classe étant basculée. Surtout la classe x-add qui devrait être détectée par le navigateur avant l'application des classes suivantes.

est Ci-dessous un exemple de travail:

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>