@@ -185,6 +185,41 @@ export default {
185
185
itemHeight: ' setDirty' ,
186
186
},
187
187
188
+ created () {
189
+ this .$_ready = false
190
+ this .$_startIndex = 0
191
+ this .$_oldScrollTop = null
192
+ this .$_oldScrollBottom = null
193
+ this .$_offsetTop = 0
194
+ this .$_height = 0
195
+ this .$_scrollDirty = false
196
+ this .$_updateDirty = false
197
+
198
+ const prerender = parseInt (this .prerender )
199
+ if (prerender > 0 ) {
200
+ this .visibleItems = this .items .slice (0 , prerender)
201
+ this .$_length = this .visibleItems .length
202
+ this .$_endIndex = this .$_length - 1
203
+ this .$_skip = true
204
+ } else {
205
+ this .$_endIndex = 0
206
+ this .$_length = 0
207
+ this .$_skip = false
208
+ }
209
+ },
210
+
211
+ mounted () {
212
+ this .applyPageMode ()
213
+ this .$nextTick (() => {
214
+ this .updateVisibleItems (true )
215
+ this .$_ready = true
216
+ })
217
+ },
218
+
219
+ beforeDestroy () {
220
+ this .removeWindowScroll ()
221
+ },
222
+
188
223
methods: {
189
224
getScroll () {
190
225
const el = this .$el
@@ -220,113 +255,120 @@ export default {
220
255
},
221
256
222
257
updateVisibleItems (force = false ) {
223
- const l = this .items .length
224
- const scroll = this .getScroll ()
225
- const items = this .items
226
- const itemHeight = this .itemHeight
227
- let containerHeight, offsetTop
228
- if (scroll) {
229
- let startIndex = - 1
230
- let endIndex = - 1
231
-
232
- const buffer = parseInt (this .buffer )
233
- const poolSize = parseInt (this .poolSize )
234
- const scrollTop = ~~ (scroll .top / poolSize) * poolSize - buffer
235
- const scrollBottom = Math .ceil (scroll .bottom / poolSize) * poolSize + buffer
236
-
237
- if (! force && ((scrollTop === this ._oldScrollTop && scrollBottom === this ._oldScrollBottom ) || this ._skip )) {
238
- this ._skip = false
239
- return
240
- } else {
241
- this ._oldScrollTop = scrollTop
242
- this ._oldScrollBottom = scrollBottom
243
- }
244
-
245
- // Variable height mode
246
- if (itemHeight === null ) {
247
- const heights = this .heights
248
- let h
249
- let a = 0
250
- let b = l - 1
251
- let i = ~~ (l / 2 )
252
- let oldI
253
-
254
- // Searching for startIndex
255
- do {
256
- oldI = i
257
- h = heights[i]
258
- if (h < scrollTop) {
259
- a = i
260
- } else if (i < l && heights[i + 1 ] > scrollTop) {
261
- b = i
258
+ if (! this .$_updateDirty ) {
259
+ this .$_updateDirty = true
260
+ this .$nextTick (() => {
261
+ this .$_updateDirty = false
262
+
263
+ const l = this .items .length
264
+ const scroll = this .getScroll ()
265
+ const items = this .items
266
+ const itemHeight = this .itemHeight
267
+ let containerHeight, offsetTop
268
+ if (scroll) {
269
+ let startIndex = - 1
270
+ let endIndex = - 1
271
+
272
+ const buffer = parseInt (this .buffer )
273
+ const poolSize = parseInt (this .poolSize )
274
+ const scrollTop = ~~ (scroll .top / poolSize) * poolSize - buffer
275
+ const scrollBottom = Math .ceil (scroll .bottom / poolSize) * poolSize + buffer
276
+
277
+ if (! force && ((scrollTop === this .$_oldScrollTop && scrollBottom === this .$_oldScrollBottom ) || this .$_skip )) {
278
+ this .$_skip = false
279
+ return
280
+ } else {
281
+ this .$_oldScrollTop = scrollTop
282
+ this .$_oldScrollBottom = scrollBottom
262
283
}
263
- i = ~~ ((a + b) / 2 )
264
- } while (i !== oldI)
265
- i < 0 && (i = 0 )
266
- startIndex = i
267
-
268
- // For containers style
269
- offsetTop = i > 0 ? heights[i - 1 ] : 0
270
- containerHeight = heights[l - 1 ]
271
-
272
- // Searching for endIndex
273
- for (endIndex = i; endIndex < l && heights[endIndex] < scrollBottom; endIndex++ );
274
- if (endIndex === - 1 ) {
275
- endIndex = items .length - 1
276
- } else {
277
- endIndex++
278
- // Bounds
279
- endIndex > l && (endIndex = l)
280
- }
281
- } else {
282
- // Fixed height mode
283
- startIndex = ~~ (scrollTop / itemHeight)
284
- endIndex = Math .ceil (scrollBottom / itemHeight)
285
284
286
- // Bounds
287
- startIndex < 0 && (startIndex = 0 )
288
- endIndex > l && (endIndex = l)
289
-
290
- offsetTop = startIndex * itemHeight
291
- containerHeight = l * itemHeight
292
- }
293
-
294
- if (
295
- force ||
296
- this ._startIndex !== startIndex ||
297
- this ._endIndex !== endIndex ||
298
- this ._offsetTop !== offsetTop ||
299
- this ._height !== containerHeight ||
300
- this ._length !== l
301
- ) {
302
- this .keysEnabled = ! (startIndex > this ._endIndex || endIndex < this ._startIndex )
303
-
304
- this .itemContainerStyle = {
305
- height: containerHeight + ' px' ,
306
- }
307
- this .itemsStyle = {
308
- marginTop: offsetTop + ' px' ,
309
- }
285
+ // Variable height mode
286
+ if (itemHeight === null ) {
287
+ const heights = this .heights
288
+ let h
289
+ let a = 0
290
+ let b = l - 1
291
+ let i = ~~ (l / 2 )
292
+ let oldI
293
+
294
+ // Searching for startIndex
295
+ do {
296
+ oldI = i
297
+ h = heights[i]
298
+ if (h < scrollTop) {
299
+ a = i
300
+ } else if (i < l && heights[i + 1 ] > scrollTop) {
301
+ b = i
302
+ }
303
+ i = ~~ ((a + b) / 2 )
304
+ } while (i !== oldI)
305
+ i < 0 && (i = 0 )
306
+ startIndex = i
307
+
308
+ // For containers style
309
+ offsetTop = i > 0 ? heights[i - 1 ] : 0
310
+ containerHeight = heights[l - 1 ]
311
+
312
+ // Searching for endIndex
313
+ for (endIndex = i; endIndex < l && heights[endIndex] < scrollBottom; endIndex++ );
314
+ if (endIndex === - 1 ) {
315
+ endIndex = items .length - 1
316
+ } else {
317
+ endIndex++
318
+ // Bounds
319
+ endIndex > l && (endIndex = l)
320
+ }
321
+ } else {
322
+ // Fixed height mode
323
+ startIndex = ~~ (scrollTop / itemHeight)
324
+ endIndex = Math .ceil (scrollBottom / itemHeight)
325
+
326
+ // Bounds
327
+ startIndex < 0 && (startIndex = 0 )
328
+ endIndex > l && (endIndex = l)
329
+
330
+ offsetTop = startIndex * itemHeight
331
+ containerHeight = l * itemHeight
332
+ }
310
333
311
- if (this .delayPreviousItems ) {
312
- // Add next items
313
- this .visibleItems = items .slice (this ._startIndex , endIndex)
314
- // Remove previous items
315
- this .$nextTick (() => {
316
- this .visibleItems = items .slice (startIndex, endIndex)
317
- })
318
- } else {
319
- this .visibleItems = items .slice (startIndex, endIndex)
334
+ if (
335
+ force ||
336
+ this .$_startIndex !== startIndex ||
337
+ this .$_endIndex !== endIndex ||
338
+ this .$_offsetTop !== offsetTop ||
339
+ this .$_height !== containerHeight ||
340
+ this .$_length !== l
341
+ ) {
342
+ this .keysEnabled = ! (startIndex > this .$_endIndex || endIndex < this .$_startIndex )
343
+
344
+ this .itemContainerStyle = {
345
+ height: containerHeight + ' px' ,
346
+ }
347
+ this .itemsStyle = {
348
+ marginTop: offsetTop + ' px' ,
349
+ }
350
+
351
+ if (this .delayPreviousItems ) {
352
+ // Add next items
353
+ this .visibleItems = items .slice (this .$_startIndex , endIndex)
354
+ // Remove previous items
355
+ this .$nextTick (() => {
356
+ this .visibleItems = items .slice (startIndex, endIndex)
357
+ })
358
+ } else {
359
+ this .visibleItems = items .slice (startIndex, endIndex)
360
+ }
361
+
362
+ this .emitUpdate && this .$emit (' update' , startIndex, endIndex)
363
+
364
+ this .$_startIndex = startIndex
365
+ this .$_endIndex = endIndex
366
+ this .$_length = l
367
+ this .$_offsetTop = offsetTop
368
+ this .$_height = containerHeight
369
+ }
320
370
}
321
-
322
- this .emitUpdate && this .$emit (' update' , startIndex, endIndex)
323
-
324
- this ._startIndex = startIndex
325
- this ._endIndex = endIndex
326
- this ._length = l
327
- this ._offsetTop = offsetTop
328
- this ._height = containerHeight
329
- }
371
+ })
330
372
}
331
373
},
332
374
@@ -341,8 +383,8 @@ export default {
341
383
},
342
384
343
385
setDirty () {
344
- this ._oldScrollTop = null
345
- this ._oldScrollBottom = null
386
+ this .$ _oldScrollTop = null
387
+ this .$ _oldScrollBottom = null
346
388
},
347
389
348
390
applyPageMode () {
@@ -364,56 +406,29 @@ export default {
364
406
},
365
407
366
408
handleScroll () {
367
- this .updateVisibleItems ()
409
+ if (! this .$_scrollDirty ) {
410
+ this .$_scrollDirty = true
411
+ requestAnimationFrame (() => {
412
+ this .$_scrollDirty = false
413
+ this .updateVisibleItems ()
414
+ })
415
+ }
368
416
},
369
417
370
418
handleResize () {
371
419
this .$emit (' resize' )
372
- this ._ready && this .updateVisibleItems ()
420
+ this .$ _ready && this .updateVisibleItems ()
373
421
},
374
422
375
423
handleVisibilityChange (isVisible , entry ) {
376
- if (this ._ready && (isVisible || entry .boundingClientRect .width !== 0 || entry .boundingClientRect .height !== 0 )) {
424
+ if (this .$ _ready && (isVisible || entry .boundingClientRect .width !== 0 || entry .boundingClientRect .height !== 0 )) {
377
425
this .$emit (' visible' )
378
426
this .$nextTick (() => {
379
427
this .updateVisibleItems ()
380
428
})
381
429
}
382
430
},
383
431
},
384
-
385
- created () {
386
- this ._ready = false
387
- this ._startIndex = 0
388
- this ._oldScrollTop = null
389
- this ._oldScrollBottom = null
390
- this ._offsetTop = 0
391
- this ._height = 0
392
- const prerender = parseInt (this .prerender )
393
- if (prerender > 0 ) {
394
- this .visibleItems = this .items .slice (0 , prerender)
395
- this ._length = this .visibleItems .length
396
- this ._endIndex = this ._length - 1
397
- this ._skip = true
398
- } else {
399
- this ._endIndex = 0
400
- this ._length = 0
401
- this ._skip = false
402
- }
403
- },
404
-
405
- mounted () {
406
- this .applyPageMode ()
407
- this .$nextTick (() => {
408
- this .updateVisibleItems (true )
409
- this ._ready = true
410
- this .$nextTick (this .updateVisibleItems )
411
- })
412
- },
413
-
414
- beforeDestroy () {
415
- this .removeWindowScroll ()
416
- },
417
432
}
418
433
</script >
419
434
0 commit comments