Skip to content

Commit ca4ae94

Browse files
authored
Merge pull request #4 from turbolent/invalidate-elements
Invalidate elements
2 parents aaebbcd + 5a7830f commit ca4ae94

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

examples/change-size/src/index.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ class Delegate {
2020
}
2121

2222
function newLayout(large) {
23-
const layout = new GridLayout()
24-
layout.itemSize = large ? [260, 260] : [180, 180]
25-
return layout
23+
const itemSize = large ? [260, 260] : [180, 180]
24+
return new GridLayout({itemSize})
2625
}
2726

2827
window.onload = function () {

src/collection-view.ts

+31-16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const TRANSITION_END_EVENT = 'transitionend'
1111
export interface CollectionViewDelegate {
1212
getCount(): number
1313
configureElement(element: HTMLElement, index: number): void
14+
invalidateElement?(element: HTMLElement, index: number): void
1415
onScroll?(collectionView: CollectionView): void
1516
}
1617

@@ -162,12 +163,8 @@ export default class CollectionView {
162163
elementHandler(element))
163164
}
164165

165-
this._elements.forEach((element) => {
166-
const parent = element.parentElement
167-
if (parent) {
168-
parent.removeChild(element)
169-
}
170-
})
166+
this._elements.forEach((element) =>
167+
this.removeElement(element))
171168
}
172169

173170
private get currentContainerSize(): NumberTuple {
@@ -249,8 +246,9 @@ export default class CollectionView {
249246
this.updateIndices(this.currentIndices)
250247
}
251248

249+
// update elements when viewport changes (e.g. when scrolling)
252250
private updateIndices(newIndices: number[]): void {
253-
// determine old elements
251+
// determine old elements. save invalid elements so they can be reused
254252
const invalidElements: HTMLElement[] = []
255253

256254
this._elements.forEach((element, index) => {
@@ -259,13 +257,18 @@ export default class CollectionView {
259257
}
260258

261259
this._elements.delete(index)
260+
if (this.delegate.invalidateElement) {
261+
this.delegate.invalidateElement(element, index)
262+
}
263+
262264
invalidElements.push(element)
263265
})
264266

265267
// add missing elements
266268
const currentIndices = this._visibleIndices
267269
newIndices.filter((index) => currentIndices.indexOf(index) < 0)
268270
.forEach((index) => {
271+
// reuse one of the invalid/old elements, or create a new element
269272
const element = invalidElements.pop()
270273
|| this.createAndAddElement()
271274
this.configureElement(this._layout, element, index)
@@ -280,10 +283,7 @@ export default class CollectionView {
280283
if (element == null) {
281284
return
282285
}
283-
const parent = element.parentElement
284-
if (parent) {
285-
parent.removeChild(element)
286-
}
286+
this.removeElement(element)
287287
})
288288
}
289289

@@ -384,6 +384,8 @@ export default class CollectionView {
384384
}
385385

386386
setTimeout(() => {
387+
this.updateIndices(futureIndices)
388+
387389
if (completion) {
388390
completion()
389391
}
@@ -420,6 +422,15 @@ export default class CollectionView {
420422
requestAnimationFrame(scroll)
421423
}
422424

425+
private removeElement(element: HTMLElement) {
426+
const parent = element.parentElement
427+
if (!parent) {
428+
return;
429+
}
430+
431+
parent.removeChild(element)
432+
}
433+
423434
public changeIndices(removedIndices: number[], addedIndices: number[], movedIndexMap: Map<number, number>): void {
424435

425436
// handle legacy Object
@@ -489,12 +500,16 @@ export default class CollectionView {
489500

490501
element.classList.add(this.disappearingClassName)
491502
element.style.zIndex = '0'
503+
504+
// NOTE: notify delegate about invalidation after element was removed
505+
// (animation finished), not immediately when stopping to keep track of it
492506
setTimeout(() => {
493-
const parent = element.parentElement
494-
if (parent) {
495-
parent.removeChild(element)
496-
}
497-
}, this.animationDuration)
507+
this.removeElement(element)
508+
if (this.delegate.invalidateElement) {
509+
this.delegate.invalidateElement(element, index)
510+
}
511+
},
512+
this.animationDuration)
498513
this._elements.delete(index)
499514
})
500515

0 commit comments

Comments
 (0)