2016-06-30 11 views
0

これは私が達成しようとしている遷移を使用して、ng-classアニメーションの大幅に簡略化されたデモです。ng-classベースのng-animateトランジションが機能しないのはなぜですか?

アイテムが選択されたときに単純なフェードを作成しようとしています。

アイテムを選択すると、ng-classディレクティブを使用して、selectedクラスが追加されます。アニメーションフッククラスをng-animateで追加したdocumentationに続いてトランジションを追加しようとしています。

以下は、これまでのコードです。遷移プロパティと共にopacity0に設定し、.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: 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>

なぜ私のコードは動作しませんか?

答えて

3

ここでの問題は、角度ng-animateがCSSクラスを適用する順序とブラウザがDOMリフローを最適化する方法のようです。

ng-animateは、実際にはクラスxを追加する前に、最初にx-addクラスを追加します。これは、ブラウザがアニメーションの初期状態を検出するようにDOMリフローを強制する(または偽造する)場所です。

しかし、初期状態のCSS(.item.selected.selected-add)のセレクタはまだ追加されていない.selectedクラスでチェーンされているため、何も一致せず、ブラウザは無視します。

この後、ng-animateselectedクラスに続いてselected-add-activeクラスを追加します。この時点で、初期状態のCSSセレクタは一致しないが、これらの変化は同じリフローで行われ、したがってブラウザはでない実際の変化が今

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

最も高い特異性を有するセレクタからopacityを適用することを選択します要素のopacityが検出された場合、遷移は行われません。


クラスがトグルされた状態でng-animateで追加されたアニメーションのフッククラスをチェーン避けるため、これを修正するには。特に、x-addクラスは、次のクラスが適用される前にブラウザーで検出される必要があります。

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>

:以下

は実施例であります
関連する問題