-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathindex.js
90 lines (71 loc) · 2.04 KB
/
index.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
79
80
81
82
83
84
85
86
87
88
89
90
var tracking = [];
const throttle = require('lodash.throttle');
const defaults = require('lodash.defaults');
const defaultOptions = {top: 0, bottom: 0, left: 0, right: 0};
const _onScroll = throttle(() => window.requestAnimationFrame(checkForVisibleElements), 100, {leading: false});
function getTracking() {
return tracking;
}
function isVisible(elm, options) {
let rect = elm.getBoundingClientRect();
return rect.bottom - options.bottom > 0 &&
rect.right - options.right > 0 &&
rect.left + options.left < (window.innerWidth || document.documentElement.clientWidth) &&
rect.top + options.top < (window.innerHeight || document.documentElement.clientHeight);
}
function _handleVisible(elm, fn, options) {
untrack(elm);
fn(elm);
}
function _trackNewElement(elm, fn, options) {
if (isVisible(elm, options)) {
return _handleVisible(elm, fn, options);
}
tracking.push({elm: elm, fn: fn, options: options});
}
function checkForVisibleElements() {
Array.from(tracking).forEach((v) => {
if (isVisible(v.elm, v.options)) {
_handleVisible(v.elm, v.fn, v.options);
}
});
if (tracking.length === 0) {
untrackAll();
}
}
function track(elm, fn, options) {
if (elm.length) {
elm = Array.from(elm);
}
let elements = [].concat(elm);
if (typeof fn !== 'function') {
throw new Error('You must pass a callback function');
}
options = defaults(options, defaultOptions);
window.requestAnimationFrame(() => {
elements.forEach(element => {
_trackNewElement(element, fn, options);
if (tracking.length === 1) {
window.addEventListener('scroll', _onScroll);
}
});
});
return elements;
}
function untrackAll() {
tracking = [];
window.removeEventListener('scroll', _onScroll);
}
function untrack(elm) {
let elmIndex = -1;
tracking.some((v, i) => {
if (v.elm == elm) {
elmIndex = i;
return true;
}
});
if (elmIndex !== -1) {
tracking.splice(elmIndex, 1);
}
}
export default {track, untrackAll, untrack, checkForVisibleElements, getTracking};