Skip to content

Commit

Permalink
fix(repeat-scrolling): correctly determine scrolltop when scrollr el …
Browse files Browse the repository at this point in the history
…is not documentElement
  • Loading branch information
bigopon committed Mar 4, 2019
1 parent c0afdb5 commit e8e14a1
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 26 deletions.
10 changes: 3 additions & 7 deletions src/array-virtual-repeat-strategy.ts
Expand Up @@ -167,7 +167,7 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy implements I
) {
let viewIndex = this._getViewIndex(repeat, repeat.viewSlot, collectionIndex);
let overrideContext = createFullOverrideContext(repeat, array[collectionIndex], collectionIndex, array.length);
repeat.removeView(viewIndex, true, true);
repeat.removeView(viewIndex, /*return to cache?*/true, /*skip animation?*/true);
repeat.insertView(viewIndex, overrideContext.bindingContext, overrideContext);
}
}
Expand Down Expand Up @@ -310,11 +310,11 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy implements I
repeat._calcInitialHeights(1);
} else if (repeat.viewCount() > repeat._viewsLength) {
if (hasDistanceToBottomViewPort) {
repeat.removeView(0, true, true);
repeat.removeView(0, /*return to cache?*/true, /*skip animation?*/true);
repeat._topBufferHeight = repeat._topBufferHeight + repeat.itemHeight;
repeat._updateBufferElements();
} else {
repeat.removeView(repeat.viewCount() - 1, true, true);
repeat.removeView(repeat.viewCount() - 1, /*return to cache?*/true, /*skip animation?*/true);
repeat._bottomBufferHeight = repeat._bottomBufferHeight + repeat.itemHeight;
}
}
Expand All @@ -328,8 +328,4 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy implements I
}
repeat._updateBufferElements();
}

onScroll(newInfo: IScrollerInfo, oldInfo: IScrollerInfo): void {

}
}
5 changes: 0 additions & 5 deletions src/interfaces.ts
Expand Up @@ -72,11 +72,6 @@ export interface IVirtualRepeatStrategy extends RepeatStrategy {
* @param splices Records of array changes.
*/
instanceMutated(repeat: VirtualRepeat, array: any[], splices: ICollectionObserverSplice[]): void;

/**
* Handle repeat scroller scroll
*/
onScroll(newInfo: IScrollerInfo, newTop: IScrollerInfo): void;
}

/**
Expand Down
2 changes: 0 additions & 2 deletions src/null-virtual-repeat-strategy.ts
Expand Up @@ -13,6 +13,4 @@ export class NullVirtualRepeatStrategy extends NullRepeatStrategy implements IVi
repeat.removeAllViews(/**return to cache?*/true, /**skip animation?*/false);
repeat._resetCalculation();
}

onScroll() {}
}
4 changes: 2 additions & 2 deletions src/template-strategy-default.ts
Expand Up @@ -42,7 +42,7 @@ export class DefaultTemplateStrategy implements ITemplateStrategy {
return lastEl === topBuffer ? null : lastEl;
}

getTopBufferDistance(topBuffer: Element): number {
return 0;
getTopBufferDistance(topBuffer: HTMLElement): number {
return topBuffer.offsetTop;
}
}
35 changes: 25 additions & 10 deletions src/virtual-repeat.ts
Expand Up @@ -337,10 +337,12 @@ export class VirtualRepeat extends AbstractRepeater {

/**@override */
detached(): void {
if (hasOverflowScroll(this.scrollContainer)) {
this.scrollContainer.removeEventListener('scroll', this.scrollListener);
const scrollCt = this.scrollContainer;
const scrollListener = this.scrollListener;
if (hasOverflowScroll(scrollCt)) {
scrollCt.removeEventListener('scroll', scrollListener);
} else {
DOM.removeEventListener('scroll', this.scrollListener, false);
DOM.removeEventListener('scroll', scrollListener, false);
}
this.isLastIndex = undefined;
this._fixedHeightContainer = false;
Expand All @@ -351,12 +353,12 @@ export class VirtualRepeat extends AbstractRepeater {
this.topBufferEl = this.bottomBufferEl = this.scrollContainer = this.scrollListener = null;
this.scrollContainerHeight = 0;
this.distanceToTop = 0;
this.removeAllViews(true, false);
this.removeAllViews(/*return to cache?*/true, /*skip animation?*/false);
this._unsubscribeCollection();
PLATFORM.global.clearInterval(this._calcDistanceToTopInterval);
if (this._sizeInterval) {
PLATFORM.global.clearInterval(this._sizeInterval);
}
const $clearInterval = PLATFORM.global.clearInterval;
$clearInterval(this._calcDistanceToTopInterval);
$clearInterval(this._sizeInterval);
this._sizeInterval = this._calcDistanceToTopInterval = 0;
}

/**@override */
Expand Down Expand Up @@ -393,7 +395,11 @@ export class VirtualRepeat extends AbstractRepeater {
const items = this.items;
const shouldCalculateSize = !!items;
const strategy = this.strategy = this.strategyLocator.getStrategy(items);


if (strategy === null) {
throw new Error('Value is not iterateable for virtual repeat.');
}

if (shouldCalculateSize) {
const currentItemCount = items.length;
if (currentItemCount > 0 && this.viewCount() === 0) {
Expand Down Expand Up @@ -556,8 +562,17 @@ export class VirtualRepeat extends AbstractRepeater {
return;
}
const itemHeight = this.itemHeight;
const topBufferDistance = this.templateStrategy.getTopBufferDistance(this.topBufferEl);
/**
* Real scroll top calculated based on current scroll top of scroller and top buffer {height + distance to top}
* as there could be elements before top buffer and it affects real scroll top of the selected repeat
*
* Calculation are done differently based on the scroller:
* - not document: the scroll top of this repeat is calculated based on current scroller.scrollTop and the distance to top of `top buffer`
* - document: the scroll top is the substraction of `pageYOffset` and distance to top of current buffer element (logic needs revised)
*/
const scrollTop = this._fixedHeightContainer
? this.scrollContainer.scrollTop
? (this.scrollContainer.scrollTop - topBufferDistance)
: (pageYOffset - this.distanceToTop);
const scrollerInfo = this.getScrollerInfo();
const elementsInView = this.elementsInView;
Expand Down

0 comments on commit e8e14a1

Please sign in to comment.