-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscroll.js
More file actions
132 lines (107 loc) · 3.9 KB
/
scroll.js
File metadata and controls
132 lines (107 loc) · 3.9 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict';
class ScrollObserver {
constructor(animateOnce = false, options = {
root: null,
threshold: 0.8,
rootMargin: '-10px',
}) {
this.options = options;
this.animateOnce = animateOnce;
this.observers = [];
}
// Create the observe method
observe(elements, callback, animationClass) {
// In case a single element is passed in, convert it to an array so array methods can be used
if (!elements || typeof elements[Symbol.iterator] !== 'function') {
elements = [elements];
}
// Create a new intersection observer
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
if (animationClass) {
if (animationClass.startsWith('scrolljs-')) {
this._removeHiddenClass(entry.target, animationClass);
}
entry.target.classList.add(animationClass);
} else {
console.error(`Error: animation class name is not defined`);
}
if (callback) {
callback(entry.target);
}
}
if (!this.animateOnce && !entry.isIntersecting) {
if (animationClass) {
entry.target.classList.remove(animationClass);
if (animationClass.startsWith('scrolljs-')) {
this._addHiddenClass(entry.target, animationClass);
}
} else {
console.error(`Error: animation class name is not defined`);
}
if (callback) {
callback(entry.target);
}
}
});
}, this.options);
// Loop through all elements and observe each of them
elements.forEach(element => {
observer.observe(element);
// Ensure element starts hidden if using scrolljs- animation class
if (animationClass && animationClass.startsWith('scrolljs-')) {
this._addHiddenClass(element, animationClass);
}
});
// Push both the observer and elements it's observing to the observers array
this.observers.push({ observer, elements });
}
unobserve(element) {
let found = false;
// Loop through each observer to check if it observes the element
this.observers.forEach(({ observer, elements }) => {
const elementsArray = Array.from(elements);
// Check if the element exists in the current observer's elements array
if (elementsArray.includes(element)) {
observer.unobserve(element);
if (element.id) {
console.log(`Element with id of "${element.id}" unobserved successfully`);
} else {
console.log(`Element with class name of "${element.classList}" unobserved successfully`);
}
found = true;
}
});
if (!found) {
console.log('Element not found in any observer:', element.id);
}
}
disconnect() {
this.observers.forEach(({ observer }) => observer.disconnect());
this.observers = [];
}
// Private methods for handling hidden classes
_addHiddenClass(element, animationClass) {
const directionMatch = animationClass.match(/-(up|down|left|right|zoom)/);
const direction = directionMatch ? directionMatch[1] : null;
if (!direction) return;
const hiddenClass = `scrolljs-hidden-${direction}`;
if (!element.classList.contains(hiddenClass)) {
element.classList.add(hiddenClass);
}
if (animationClass.includes('fade') && !element.classList.contains('scrolljs-opacity-0')) {
element.classList.add('scrolljs-opacity-0');
}
}
_removeHiddenClass(element, animationClass) {
const directionMatch = animationClass.match(/-(up|down|left|right|zoom)/);
const direction = directionMatch ? directionMatch[1] : null;
if (!direction) return;
const hiddenClass = `scrolljs-hidden-${direction}`;
element.classList.remove(hiddenClass);
if (animationClass.includes('fade')) {
element.classList.remove('scrolljs-opacity-0');
}
}
}