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
This commit is contained in:
committed by
Martin Staffa
parent
20bc37fbc8
commit
a3a7afd3aa
@@ -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;
|
||||
|
||||
|
||||
@@ -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/);
|
||||
|
||||
Reference in New Issue
Block a user