From 783fb22cce3807de702c5bc2e7f2a4e7e9e82b22 Mon Sep 17 00:00:00 2001 From: Jarek Rencz Date: Wed, 1 Jul 2015 11:38:13 +0200 Subject: [PATCH] Prevent layout trashing where possible by using $applyAsync --- angular-viewport-watch.js | 23 +++++++++++++++++------ dist/scripts/angular-viewport-watch.js | 23 +++++++++++++++++------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/angular-viewport-watch.js b/angular-viewport-watch.js index b7590b8..47a0f89 100644 --- a/angular-viewport-watch.js +++ b/angular-viewport-watch.js @@ -12,7 +12,7 @@ return { restrict: "AE", link: function(scope, element, attr) { - var elementWatcher = scrollMonitor.create(element, scope.$eval(attr.viewportWatch || "0")); + var elementWatcher; function watchDuringDisable() { this.$$watchersBackup = this.$$watchersBackup || []; this.$$watchers = this.$$watchersBackup; @@ -56,12 +56,23 @@ function enableDigest() { toggleWatchers(scope, true); } - if (!elementWatcher.isInViewport) { - scope.$evalAsync(disableDigest); - debouncedViewportUpdate(); + function createElementWatcher() { + elementWatcher = scrollMonitor.create(element, scope.$eval(attr.viewportWatch || "0")); + if (!elementWatcher.isInViewport) { + scope.$evalAsync(disableDigest); + debouncedViewportUpdate(); + } + elementWatcher.enterViewport(enableDigest); + elementWatcher.exitViewport(disableDigest); + } + if ('$applyAsync' in scope) { + // Wrapping scrollMonitor creation in $applyAsync prevents layout trashing in case this directive + // is applied to ngRepeat-ed elements. + scope.$applyAsync(createElementWatcher); + } else { + // Angular pre-1.3 compatibility. Will cause Layout when each ngRepeat-ed element is rendered. + createElementWatcher(); } - elementWatcher.enterViewport(enableDigest); - elementWatcher.exitViewport(disableDigest); scope.$on("toggleWatchers", function(event, enable) { toggleWatchers(scope, enable); }); diff --git a/dist/scripts/angular-viewport-watch.js b/dist/scripts/angular-viewport-watch.js index b7590b8..47a0f89 100644 --- a/dist/scripts/angular-viewport-watch.js +++ b/dist/scripts/angular-viewport-watch.js @@ -12,7 +12,7 @@ return { restrict: "AE", link: function(scope, element, attr) { - var elementWatcher = scrollMonitor.create(element, scope.$eval(attr.viewportWatch || "0")); + var elementWatcher; function watchDuringDisable() { this.$$watchersBackup = this.$$watchersBackup || []; this.$$watchers = this.$$watchersBackup; @@ -56,12 +56,23 @@ function enableDigest() { toggleWatchers(scope, true); } - if (!elementWatcher.isInViewport) { - scope.$evalAsync(disableDigest); - debouncedViewportUpdate(); + function createElementWatcher() { + elementWatcher = scrollMonitor.create(element, scope.$eval(attr.viewportWatch || "0")); + if (!elementWatcher.isInViewport) { + scope.$evalAsync(disableDigest); + debouncedViewportUpdate(); + } + elementWatcher.enterViewport(enableDigest); + elementWatcher.exitViewport(disableDigest); + } + if ('$applyAsync' in scope) { + // Wrapping scrollMonitor creation in $applyAsync prevents layout trashing in case this directive + // is applied to ngRepeat-ed elements. + scope.$applyAsync(createElementWatcher); + } else { + // Angular pre-1.3 compatibility. Will cause Layout when each ngRepeat-ed element is rendered. + createElementWatcher(); } - elementWatcher.enterViewport(enableDigest); - elementWatcher.exitViewport(disableDigest); scope.$on("toggleWatchers", function(event, enable) { toggleWatchers(scope, enable); });