* 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 = {};
|
const observersByDotNetId = {};
|
||||||
|
|
||||||
function findClosestScrollContainer(element: Element | null): Element | null {
|
function findClosestScrollContainer(element: HTMLElement | null): HTMLElement | null {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -20,8 +20,14 @@ function findClosestScrollContainer(element: Element | null): Element | null {
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(dotNetHelper: any, spacerBefore: HTMLElement, spacerAfter: HTMLElement, rootMargin = 50): void {
|
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, {
|
const intersectionObserver = new IntersectionObserver(intersectionCallback, {
|
||||||
root: findClosestScrollContainer(spacerBefore),
|
root: scrollContainer,
|
||||||
rootMargin: `${rootMargin}px`,
|
rootMargin: `${rootMargin}px`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -57,7 +63,9 @@ function init(dotNetHelper: any, spacerBefore: HTMLElement, spacerAfter: HTMLEle
|
||||||
return;
|
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;
|
const containerSize = entry.rootBounds?.height;
|
||||||
|
|
||||||
if (entry.target === spacerBefore) {
|
if (entry.target === spacerBefore) {
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,15 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public ICollection<TItem>? Items { get; set; }
|
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 />
|
/// <inheritdoc />
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
|
|
@ -251,8 +260,8 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
|
||||||
_itemSize = ItemSize;
|
_itemSize = ItemSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemsInSpacer = Math.Max(0, (int)Math.Floor(spacerSize / _itemSize) - 1);
|
itemsInSpacer = Math.Max(0, (int)Math.Floor(spacerSize / _itemSize) - OverscanCount);
|
||||||
visibleItemCapacity = (int)Math.Ceiling(containerSize / _itemSize) + 2;
|
visibleItemCapacity = (int)Math.Ceiling(containerSize / _itemSize) + 2 * OverscanCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity)
|
private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue