* Use ItemSize if it's close to the calculated item size. * Update WeatherForecastService.cs * Improved item size calculation. * Always use calculated item size * Disable overflow anchoring on scroll containers (except the document itself) * Update JS files following rebase * Apply overflow anchor fix to document element too * Add OverscanCount parameter Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
This commit is contained in:
parent
12c016567c
commit
8418ef66e3
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -5,7 +5,7 @@ export const Virtualize = {
|
|||
|
||||
const observersByDotNetId = {};
|
||||
|
||||
function findClosestScrollContainer(element: Element | null): Element | null {
|
||||
function findClosestScrollContainer(element: HTMLElement | null): HTMLElement | null {
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -20,8 +20,14 @@ function findClosestScrollContainer(element: Element | null): Element | null {
|
|||
}
|
||||
|
||||
function init(dotNetHelper: any, spacerBefore: HTMLElement, spacerAfter: HTMLElement, rootMargin = 50): void {
|
||||
// Overflow anchoring can cause an ongoing scroll loop, because when we resize the spacers, the browser
|
||||
// would update the scroll position to compensate. Then the spacer would remain visible and we'd keep on
|
||||
// trying to resize it.
|
||||
const scrollContainer = findClosestScrollContainer(spacerBefore);
|
||||
(scrollContainer || document.documentElement).style.overflowAnchor = 'none';
|
||||
|
||||
const intersectionObserver = new IntersectionObserver(intersectionCallback, {
|
||||
root: findClosestScrollContainer(spacerBefore),
|
||||
root: scrollContainer,
|
||||
rootMargin: `${rootMargin}px`,
|
||||
});
|
||||
|
||||
|
|
@ -57,7 +63,9 @@ function init(dotNetHelper: any, spacerBefore: HTMLElement, spacerAfter: HTMLEle
|
|||
return;
|
||||
}
|
||||
|
||||
const spacerSeparation = spacerAfter.offsetTop - (spacerBefore.offsetTop + spacerBefore.offsetHeight);
|
||||
const spacerBeforeRect = spacerBefore.getBoundingClientRect();
|
||||
const spacerAfterRect = spacerAfter.getBoundingClientRect();
|
||||
const spacerSeparation = spacerAfterRect.top - spacerBeforeRect.bottom;
|
||||
const containerSize = entry.rootBounds?.height;
|
||||
|
||||
if (entry.target === spacerBefore) {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,15 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
|
|||
[Parameter]
|
||||
public ICollection<TItem>? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines how many additional items will be rendered
|
||||
/// before and after the visible region. This help to reduce the frequency of rendering
|
||||
/// during scrolling. However, higher values mean that more elements will be present
|
||||
/// in the page.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int OverscanCount { get; set; } = 3;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
|
|
@ -251,8 +260,8 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
|
|||
_itemSize = ItemSize;
|
||||
}
|
||||
|
||||
itemsInSpacer = Math.Max(0, (int)Math.Floor(spacerSize / _itemSize) - 1);
|
||||
visibleItemCapacity = (int)Math.Ceiling(containerSize / _itemSize) + 2;
|
||||
itemsInSpacer = Math.Max(0, (int)Math.Floor(spacerSize / _itemSize) - OverscanCount);
|
||||
visibleItemCapacity = (int)Math.Ceiling(containerSize / _itemSize) + 2 * OverscanCount;
|
||||
}
|
||||
|
||||
private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity)
|
||||
|
|
|
|||
Loading…
Reference in New Issue