flex_infinite_scroll 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|