mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($animate): skip unnecessary addClass/removeClass animations
Skip addClass animations if the element already contains the class that is being added to element. Also skip removeClass animations if the element does not contain the class that is being removed. Closes #4401 Closes #2332
This commit is contained in:
parent
46d396df72
commit
76b628bcb3
2 changed files with 51 additions and 1 deletions
|
|
@ -541,6 +541,16 @@ angular.module('ngAnimate', ['ng'])
|
|||
(ngAnimateState.done || noop)();
|
||||
}
|
||||
|
||||
//There is no point in perform a class-based animation if the element already contains
|
||||
//(on addClass) or doesn't contain (on removeClass) the className being animated.
|
||||
//The reason why this is being called after the previous animations are cancelled
|
||||
//is so that the CSS classes present on the element can be properly examined.
|
||||
if((event == 'addClass' && element.hasClass(className)) ||
|
||||
(event == 'removeClass' && !element.hasClass(className))) {
|
||||
onComplete && onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
element.data(NG_ANIMATE_STATE, {
|
||||
running:true,
|
||||
structural:!isClassBased,
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ describe("ngAnimate", function() {
|
|||
|
||||
$animate.enabled(true);
|
||||
|
||||
element.addClass('ng-hide');
|
||||
$animate.removeClass(element, 'ng-hide');
|
||||
expect(element.text()).toBe('memento');
|
||||
}));
|
||||
|
|
@ -616,7 +617,7 @@ describe("ngAnimate", function() {
|
|||
ss.addRule('.ng-hide-add', style);
|
||||
ss.addRule('.ng-hide-remove', style);
|
||||
|
||||
element = $compile(html('<div>1</div>'))($rootScope);
|
||||
element = $compile(html('<div class="ng-hide">1</div>'))($rootScope);
|
||||
element.addClass('custom');
|
||||
|
||||
$animate.removeClass(element, 'ng-hide');
|
||||
|
|
@ -627,6 +628,7 @@ describe("ngAnimate", function() {
|
|||
expect(element.hasClass('ng-hide-remove-active')).toBe(true);
|
||||
}
|
||||
|
||||
element.removeClass('ng-hide');
|
||||
$animate.addClass(element, 'ng-hide');
|
||||
expect(element.hasClass('ng-hide-remove')).toBe(false); //added right away
|
||||
|
||||
|
|
@ -1052,14 +1054,17 @@ describe("ngAnimate", function() {
|
|||
});
|
||||
|
||||
describe("addClass / removeClass", function() {
|
||||
var captured;
|
||||
beforeEach(function() {
|
||||
module(function($animateProvider, $provide) {
|
||||
$animateProvider.register('.klassy', function($timeout) {
|
||||
return {
|
||||
addClass : function(element, className, done) {
|
||||
captured = 'addClass-' + className;
|
||||
$timeout(done, 500, false);
|
||||
},
|
||||
removeClass : function(element, className, done) {
|
||||
captured = 'removeClass-' + className;
|
||||
$timeout(done, 3000, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1067,6 +1072,41 @@ describe("ngAnimate", function() {
|
|||
});
|
||||
});
|
||||
|
||||
it("should not perform an animation, and the followup DOM operation, if the class is " +
|
||||
"already present during addClass or not present during removeClass on the element",
|
||||
inject(function($animate, $rootScope, $sniffer, $rootElement, $timeout) {
|
||||
|
||||
var element = jqLite('<div class="klassy"></div>');
|
||||
$rootElement.append(element);
|
||||
body.append($rootElement);
|
||||
|
||||
//skipped animations
|
||||
captured = 'none';
|
||||
$animate.removeClass(element, 'some-class');
|
||||
expect(element.hasClass('some-class')).toBe(false);
|
||||
expect(captured).toBe('none');
|
||||
|
||||
element.addClass('some-class');
|
||||
|
||||
captured = 'nothing';
|
||||
$animate.addClass(element, 'some-class');
|
||||
expect(captured).toBe('nothing');
|
||||
expect(element.hasClass('some-class')).toBe(true);
|
||||
|
||||
//actual animations
|
||||
captured = 'none';
|
||||
$animate.removeClass(element, 'some-class');
|
||||
$timeout.flush();
|
||||
expect(element.hasClass('some-class')).toBe(false);
|
||||
expect(captured).toBe('removeClass-some-class');
|
||||
|
||||
captured = 'nothing';
|
||||
$animate.addClass(element, 'some-class');
|
||||
$timeout.flush();
|
||||
expect(element.hasClass('some-class')).toBe(true);
|
||||
expect(captured).toBe('addClass-some-class');
|
||||
}));
|
||||
|
||||
it("should add and remove CSS classes after an animation even if no animation is present",
|
||||
inject(function($animate, $rootScope, $sniffer, $rootElement) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue