flex_infinite_scroll 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/vendor/assets/javascript/flex_infinite_scroll.js +126 -7
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2fd414bc8323c2bb367697232a7e2e259cfed15
|
4
|
+
data.tar.gz: 1f5f35932d20c2049a2e28734677e41a466338df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78ddf99585b446ec32503783b6a300904dec526a8489e8de03bf1d0aeac1f2291ceb26d84ad452eb23d28c1387c1b5ec3efb64370e366e78312275bf8f825473
|
7
|
+
data.tar.gz: dac2a3773a6f1538873f57d20ec97ad85b98afeef77e2bf8a90c2e5672157a5081f1ee84d4efd552b76dfeec6bf7ea1e3aba68b42a316a3c95d925c56e1155d5
|
@@ -18,7 +18,11 @@
|
|
18
18
|
customResponseAttributes: {
|
19
19
|
next_page: 'next_page',
|
20
20
|
data: 'data'
|
21
|
-
}
|
21
|
+
},
|
22
|
+
virtualScroll: 'Enable virtual scroll',
|
23
|
+
virtualScrollElementSize: 'Element size for virtual scroll',
|
24
|
+
perfectScrollbarSupport: 'Enable perfect-scrollbar support'
|
25
|
+
perfectScrollbarConfig: 'Config for perfect-scrollbar'
|
22
26
|
}
|
23
27
|
*/
|
24
28
|
|
@@ -30,6 +34,7 @@ class flexIS {
|
|
30
34
|
this.config = {...config, ...this.targetObject.dataset};
|
31
35
|
this.loading = false;
|
32
36
|
this.nextPage = this.config.startPage || 1;
|
37
|
+
this.totalElements;
|
33
38
|
|
34
39
|
this.config.requestType = this.config.requestType || 'GET';
|
35
40
|
this.config.loadMargin = this.config.loadMargin || 150;
|
@@ -44,8 +49,18 @@ class flexIS {
|
|
44
49
|
return eventTarget;
|
45
50
|
}
|
46
51
|
}
|
52
|
+
|
53
|
+
if (this.config.perfectScrollbarSupport) {
|
54
|
+
let PSConfig = this.config.perfectScrollbarConfig || {}
|
55
|
+
PSConfig.minScrollbarLength = PSConfig.minScrollbarLength || 40
|
56
|
+
this.perfectScrollbar = new PerfectScrollbar(
|
57
|
+
this.targetObject,
|
58
|
+
PSConfig
|
59
|
+
)
|
60
|
+
}
|
47
61
|
}
|
48
62
|
|
63
|
+
// Init infinite scroll
|
49
64
|
init() {
|
50
65
|
this.#getData();
|
51
66
|
this.config.eventTarget.addEventListener('scroll', () => {
|
@@ -57,6 +72,7 @@ class flexIS {
|
|
57
72
|
return this;
|
58
73
|
}
|
59
74
|
|
75
|
+
// Reset scroll to specific page
|
60
76
|
resetScroll(page) {
|
61
77
|
this.targetObject.innerHTML = '';
|
62
78
|
this.nextPage = page || this.config.startPage || 1;
|
@@ -64,8 +80,15 @@ class flexIS {
|
|
64
80
|
return this;
|
65
81
|
}
|
66
82
|
|
83
|
+
// Append element to container
|
84
|
+
appendChild(el) {
|
85
|
+
this.#appendElementToContainer(el);
|
86
|
+
return this;
|
87
|
+
}
|
88
|
+
|
67
89
|
// Private methods
|
68
90
|
|
91
|
+
// Run data request for next page
|
69
92
|
#getData = (page = this.nextPage ) => {
|
70
93
|
var xhr = new XMLHttpRequest();
|
71
94
|
var params;
|
@@ -88,6 +111,10 @@ class flexIS {
|
|
88
111
|
if (xhr.status === 200) {
|
89
112
|
this.#customResponse(json);
|
90
113
|
this.nextPage = json[this.config.customResponseAttributes.next_page];
|
114
|
+
if (this.config.virtualScroll) {
|
115
|
+
this.elementsLeft = json[this.config.customResponseAttributes.elements_left];
|
116
|
+
this.#virtualScroll().update();
|
117
|
+
}
|
91
118
|
if (this.#scrollHitBottom()) this.#getData();
|
92
119
|
}
|
93
120
|
|
@@ -97,18 +124,27 @@ class flexIS {
|
|
97
124
|
xhr.send();
|
98
125
|
}
|
99
126
|
|
127
|
+
// Full scroll height
|
100
128
|
#scrollHeight = () => {
|
101
129
|
return this.targetObject.scrollHeight;
|
102
130
|
}
|
103
131
|
|
132
|
+
// Top scroll position
|
104
133
|
#scrollTop = () => {
|
105
134
|
return this.config.eventTarget.scrollTop || this.config.eventTarget.scrollY || 0;
|
106
135
|
}
|
107
136
|
|
137
|
+
// Get container size
|
108
138
|
#containerSize = () => {
|
109
139
|
return this.config.eventTarget.innerHeight || this.targetObject.offsetHeight;
|
110
140
|
}
|
111
141
|
|
142
|
+
// Container position
|
143
|
+
#containerPosition = () => {
|
144
|
+
return this.#scrollTop() + this.#containerSize() + this.config.loadMargin
|
145
|
+
}
|
146
|
+
|
147
|
+
// Add custom params to request
|
112
148
|
#customParams = (params) => {
|
113
149
|
var customParams = this.config.customParams;
|
114
150
|
if (customParams) {
|
@@ -123,22 +159,49 @@ class flexIS {
|
|
123
159
|
return params;
|
124
160
|
}
|
125
161
|
|
162
|
+
// Response handling
|
126
163
|
#customResponse = (json) => {
|
127
164
|
var customResponse = this.config.customResponse;
|
165
|
+
var data = json[this.config.customResponseAttributes.data];
|
128
166
|
var div;
|
129
|
-
|
130
|
-
|
131
|
-
|
167
|
+
|
168
|
+
delete json[this.config.customResponseAttributes.data]
|
169
|
+
|
170
|
+
if (data.constructor === Array) {
|
171
|
+
data.forEach((el) => {
|
172
|
+
var htmlEl
|
173
|
+
if (typeof customResponse === "function") {
|
174
|
+
htmlEl = customResponse(el, json);
|
175
|
+
} else {
|
176
|
+
htmlEl = el;
|
177
|
+
}
|
178
|
+
this.#appendElementToContainer(htmlEl)
|
179
|
+
})
|
180
|
+
} else if (data.constructor === String) {
|
132
181
|
div = document.createElement('div');
|
133
|
-
div.innerHTML =
|
182
|
+
div.innerHTML = data;
|
134
183
|
while (div.children.length > 0) {
|
135
|
-
this
|
184
|
+
this.#appendElementToContainer(div.children[0])
|
136
185
|
}
|
137
186
|
}
|
138
187
|
|
139
188
|
this.#hideInvisibleContent();
|
189
|
+
|
190
|
+
if (this.perfectScrollbar) {
|
191
|
+
this.perfectScrollbar.update();
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
#appendElementToContainer = (el) => {
|
196
|
+
if (this.#virtualScroll().baloon()) {
|
197
|
+
this.targetObject.insertBefore(el, this.#virtualScroll().baloon());
|
198
|
+
} else {
|
199
|
+
this.targetObject.appendChild(el);
|
200
|
+
}
|
201
|
+
this.elementHeight = el.offsetHeight;
|
140
202
|
}
|
141
203
|
|
204
|
+
// Hide invisible content, when leaving active zone
|
142
205
|
#hideInvisibleContent = () => {
|
143
206
|
var elems = this.targetObject.children;
|
144
207
|
for (let i = 0; i < elems.length; i++) {
|
@@ -146,6 +209,8 @@ class flexIS {
|
|
146
209
|
let elementTopPosition = elems[i].offsetTop + elems[i].offsetHeight - this.#scrollTop();
|
147
210
|
let elementBottomPosition = elems[i].offsetTop - elems[i].offsetHeight - this.#scrollTop() - this.#containerSize();
|
148
211
|
|
212
|
+
if (elem.className.includes('ps__rail-x', 'ps__rail-y')) continue;
|
213
|
+
|
149
214
|
if (elementTopPosition <= 0 || elementBottomPosition >= 0) {
|
150
215
|
if (elem.style.visibility === 'hidden') continue;
|
151
216
|
elem.style.visibility = 'hidden';
|
@@ -156,13 +221,60 @@ class flexIS {
|
|
156
221
|
}
|
157
222
|
}
|
158
223
|
|
224
|
+
#virtualScroll = () => {
|
225
|
+
// Find baloon
|
226
|
+
var baloon = this.targetObject.getElementsByClassName('fis-baloon')[0];
|
227
|
+
|
228
|
+
// Create new baloon
|
229
|
+
var createBaloon = () => {
|
230
|
+
baloon = document.createElement('div');
|
231
|
+
baloon.className = 'fis-baloon';
|
232
|
+
this.targetObject.appendChild(baloon);
|
233
|
+
return baloon;
|
234
|
+
}
|
235
|
+
|
236
|
+
// Check if baloon exist and return it
|
237
|
+
var baloonAdded = () => {
|
238
|
+
if (baloon) {
|
239
|
+
return baloon;
|
240
|
+
}
|
241
|
+
return false
|
242
|
+
}
|
243
|
+
|
244
|
+
// Update baloon size
|
245
|
+
var updateScroll = () => {
|
246
|
+
var elementHeight = this.config.virtualScrollElementSize || this.elementHeight;
|
247
|
+
if (!baloonAdded()) {
|
248
|
+
baloon = createBaloon();
|
249
|
+
}
|
250
|
+
if (this.elementsLeft > 0) {
|
251
|
+
baloon.style.height = (elementHeight * this.elementsLeft) + 'px';
|
252
|
+
} else {
|
253
|
+
// Remove baloon, if no more elements to load.
|
254
|
+
baloon.remove();
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
return {
|
259
|
+
update: () => {
|
260
|
+
updateScroll()
|
261
|
+
},
|
262
|
+
baloon: () => {
|
263
|
+
return baloonAdded();
|
264
|
+
}
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
// Update response attributes
|
159
269
|
#customResponseAttributesSet = () => {
|
160
270
|
var attr = this.config.customResponseAttributes || {};
|
161
271
|
attr.next_page = attr.next_page || 'next_page';
|
162
272
|
attr.data = attr.data || 'data';
|
273
|
+
attr.elements_left = attr.elements_left || 'elements_left';
|
163
274
|
this.config.customResponseAttributes = attr
|
164
275
|
}
|
165
276
|
|
277
|
+
// Generate url with params
|
166
278
|
#requestUrl = (params) => {
|
167
279
|
var encodedString = [];
|
168
280
|
for (var prop in params) {
|
@@ -173,8 +285,15 @@ class flexIS {
|
|
173
285
|
return this.config.requestUrl + '?' + encodedString.join('&');
|
174
286
|
}
|
175
287
|
|
288
|
+
// Check when load next page
|
176
289
|
#scrollHitBottom = () => {
|
177
|
-
|
290
|
+
var hitBottom;
|
291
|
+
if (this.#virtualScroll().baloon()) {
|
292
|
+
hitBottom = this.#containerPosition() > this.#virtualScroll().baloon().offsetTop;
|
293
|
+
} else {
|
294
|
+
hitBottom = this.#scrollHeight() - this.#containerPosition() <= 0;
|
295
|
+
}
|
296
|
+
return hitBottom;
|
178
297
|
}
|
179
298
|
}
|
180
299
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flex_infinite_scroll
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Ignatov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -55,5 +55,7 @@ rubyforge_project:
|
|
55
55
|
rubygems_version: 2.6.14.3
|
56
56
|
signing_key:
|
57
57
|
specification_version: 4
|
58
|
-
summary: Infinite scroll for Ruby on Rails applications on pure JavaScript.
|
58
|
+
summary: 'Infinite scroll for Ruby on Rails applications on pure JavaScript. Supported
|
59
|
+
features: - Custom response handling. - Virtual scrollbar. - Perfect scrollbar support.
|
60
|
+
- Kaminari support.'
|
59
61
|
test_files: []
|