Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(ngAnimate): do not trigger animations if the document is hidden
Prior to this fix, ngAnimate would always trigger animations even if
the browser tab or browser window was not visible. This would cause
issues with class updates / DOM operations even if elements were not
using animations. The root cause is that browsers do not flush calls to
requestAnimationFrame when browser windows / tabs are not visible.

This fix disables animations if `document.hidden` is `true`.

Closes #12842
Closes #13776
  • Loading branch information
matsko authored and Narretz committed Jan 17, 2016
1 parent 20bc37f commit a3a7afd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/ngAnimate/animateQueue.js
Expand Up @@ -337,7 +337,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
// this is a hard disable of all animations for the application or on
// the element itself, therefore there is no need to continue further
// past this point if not enabled
var skipAnimations = !animationsEnabled || disabledElementsLookup.get(node);
// Animations are also disabled if the document is currently hidden (page is not visible
// to the user), because browsers slow down or do not flush calls to requestAnimationFrame
var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node);
var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
var hasExistingAnimation = !!existingAnimation.state;

Expand Down
25 changes: 25 additions & 0 deletions test/ngAnimate/animateSpec.js
Expand Up @@ -148,6 +148,31 @@ describe("animations", function() {
expect(copiedOptions).toEqual(initialOptions);
}));

it("should skip animations entirely if the document is hidden", function() {
var doc;

module(function($provide) {
doc = jqLite({
body: document.body,
hidden: true
});
$provide.value('$document', doc);
});

inject(function($animate, $rootScope) {
$animate.enter(element, parent);
$rootScope.$digest();
expect(capturedAnimation).toBeFalsy();
expect(element[0].parentNode).toEqual(parent[0]);

doc[0].hidden = false;

$animate.leave(element);
$rootScope.$digest();
expect(capturedAnimation).toBeTruthy();
});
});

it('should animate only the specified CSS className matched within $animateProvider.classNameFilter', function() {
module(function($animateProvider) {
$animateProvider.classNameFilter(/only-allow-this-animation/);
Expand Down

0 comments on commit a3a7afd

Please sign in to comment.