Why is ng-class based ng-animate transition not working?

跟風遠走 提交于 2019-12-07 02:52:26

The problem here seems to be the order in which angular ng-animate applies the CSS classes and how browser optimizes DOM reflows.

ng-animate initially adds the x-add class prior to actually adding class x. This is where it forces(or fakes) a DOM reflow so that browser detects the initial state for animation.

But since the selector for initial state's CSS (.item.selected.selected-add) is chained with .selected class which isn't added yet, it doesn't match anything and browser ignores it.

After this, ng-animate adds the selected class followed by selected-add-active class. At this point the CSS selector for initial state does match, but these changes happens in the same reflow, hence the browser chooses to apply opacity from the selector with highest specificity which is

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

Now since no actual change in the element's opacity is detected, no transition takes place.


To fix this, avoid chaining the animation hook classes added by ng-animate with the class being toggled. Especially the x-add class which should be detected by the browser before the following classes gets applied.

Below is a working example:

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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!