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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2557a6f5390214ce8246d233d45b74c435935816
4
- data.tar.gz: 93605b2012ff14d17244b8daecdc74bf1c605d66
3
+ metadata.gz: d2fd414bc8323c2bb367697232a7e2e259cfed15
4
+ data.tar.gz: 1f5f35932d20c2049a2e28734677e41a466338df
5
5
  SHA512:
6
- metadata.gz: 9c1e4446ee54023638482f0c251b25ebea1e16d32adb13308bd48ba1c1cff6cabed59bb3add68beda0d42f8df782cf7a6a7e14fa5f010660c156546b42757e95
7
- data.tar.gz: e7c29fb2c5aa9a8f19d14bd3d707759876f7c684e4fc79965cdd1c62d0a35e7056d7ab7a30c635469f75b49b1b43edc9479c79fab08fe28cdb271158d0cee29a
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
- if (typeof customResponse === "function") {
130
- customResponse(this.targetObject, json);
131
- } else {
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 = json[this.config.customResponseAttributes.data];
182
+ div.innerHTML = data;
134
183
  while (div.children.length > 0) {
135
- this.targetObject.appendChild(div.children[0]);
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
- return (this.#scrollHeight() - this.#scrollTop() - this.#containerSize() - this.config.loadMargin <= 0);
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.1
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-12 00:00:00.000000000 Z
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: []