-
Notifications
You must be signed in to change notification settings - Fork 41
/
angular-viewport-watch.js
78 lines (77 loc) · 3.38 KB
/
angular-viewport-watch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"use strict";
(function() {
viewportWatch.$inject = [ "scrollMonitor", "$timeout" ];
function viewportWatch(scrollMonitor, $timeout) {
var viewportUpdateTimeout;
function debouncedViewportUpdate() {
$timeout.cancel(viewportUpdateTimeout);
viewportUpdateTimeout = $timeout(function() {
scrollMonitor.update();
}, 10);
}
return {
restrict: "AE",
link: function(scope, element, attr) {
var elementWatcher = scrollMonitor.create(element, scope.$eval(attr.viewportWatch || "0"));
function watchDuringDisable() {
this.$$watchersBackup = this.$$watchersBackup || [];
this.$$watchers = this.$$watchersBackup;
var unwatch = this.constructor.prototype.$watch.apply(this, arguments);
this.$$watchers = null;
return unwatch;
}
function toggleWatchers(scope, enable) {
var digest, current, next = scope;
do {
current = next;
if (enable) {
if (current.hasOwnProperty("$$watchersBackup")) {
current.$$watchers = current.$$watchersBackup;
delete current.$$watchersBackup;
delete current.$watch;
digest = !scope.$root.$$phase;
}
} else {
if (!current.hasOwnProperty("$$watchersBackup")) {
current.$$watchersBackup = current.$$watchers;
current.$$watchers = null;
current.$watch = watchDuringDisable;
}
}
next = current.$$childHead;
while (!next && current !== scope) {
if (current.$$nextSibling) {
next = current.$$nextSibling;
} else {
current = current.$parent;
}
}
} while (next);
if (digest) {
scope.$digest();
}
}
function disableDigest() {
toggleWatchers(scope, false);
}
function enableDigest() {
toggleWatchers(scope, true);
}
if (!elementWatcher.isInViewport) {
scope.$evalAsync(disableDigest);
debouncedViewportUpdate();
}
elementWatcher.enterViewport(enableDigest);
elementWatcher.exitViewport(disableDigest);
scope.$on("toggleWatchers", function(event, enable) {
toggleWatchers(scope, enable);
});
scope.$on("$destroy", function() {
elementWatcher.destroy();
debouncedViewportUpdate();
});
}
};
}
angular.module("angularViewportWatch", []).directive("viewportWatch", viewportWatch).value("scrollMonitor", window.scrollMonitor);
})();