为什么基于ng-class的ng-animate转换不工作? [英] Why is ng-class based ng-animate transition not working?

查看:162
本文介绍了为什么基于ng-class的ng-animate转换不工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个非常简化的 ng-class 动画使用我想实现的转换。



选择一个项目将添加一个选择类使用 ng-class 指令。我正试图在文档之后向其中添加转换a>添加 ng-animate 添加的动画钩子类。



下面是我到目前为止的代码。它将 opacity 设置为 0 以及transition属性,当 .selected- add-active 类添加它应该转换到 opacity 1.但它不工作。



  angular.module('demo',['ngAnimate'])。 controller('demoCtrl',function($ scope){$ scope.selected = false; $ scope.selectToggle = function(){$ scope.selected =!$ scope.selected;};});  

  .item {width:50px; height:50px; background:gray;}。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 = demong-controller =demoCtrl> < div class =itemng-class ={selected:selected}>< / div> < br> < br> < button ng-click =selectToggle();> {{selected? 'Unselect':'选择'}}< / button>< / div>  



为什么我的代码不工作?

解决方案

这里的问题似乎是ng-animate应用CSS类以及浏览器如何优化DOM回流。



ng-animate c $ c> x-add 类,然后再实际添加类 x



但是由于初始状态的CSS(<$ c $)的选择器, c> .item.selected.selected-add )与 .selected 链接,但尚未添加,



之后, ng-animate 添加 selected 类后跟 selected-add-active 类。此时,初始状态的CSS选择器不匹配,但是这些更改发生在相同的回流,因此浏览器选择从选择器应用 opacity ,具有最高的特异性, / p>

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

现在因为元素的 / code>,则不会发生转换。






要解决这个问题,添加 ng-animate 与正在切换的类。特别是在应用以下类之前应该由浏览器检测到的 x-add 类。



一个工作示例:



  angular.module('demo',['ngAnimate ']).controller('demoCtrl',function($ scope){$ scope.selected = false; $ scope.selectToggle = function(){$ scope.selected =!$ scope.selected;};}) code> 

  .item {width:50px; height:50px; background:gray;}。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 =itemng-class ={selected:selected}>< / div> < br> < br> < button ng-click =selectToggle();> {{selected? 'Unselect':'Select'}}< / button>< / div>  

This is a heavily simplified demo of ng-class animation using transition that I'm trying to achieve.

I'm trying to create a simple fade in animation when an item is selected.

Selecting an item will add a selected class on it using ng-class directive. I'm trying to add a transition to it following the documentation with the animation hook classes added by ng-animate.

Below is the code I have so far. It sets the opacity to 0 along with the transition property, and when the .selected-add-active class is added it is supposed to transition to opacity 1. But it does not work.

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>

Why isn't my code working?

解决方案

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>

这篇关于为什么基于ng-class的ng-animate转换不工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆