fix(ui): replace full-page loading overlay with grid-scoped loader to eliminate flicker

- Add .grid-loading-overlay CSS: position:absolute inside card grid,
  semi-transparent dark background, z-index 100, pointer-events:none
- Add showGridLoading() / hideGridLoading() to VirtualScroller:
  creates/removes the scoped overlay inside the card grid only
- Modify loadMoreWithVirtualScroll(): replace full-page
  state.loadingManager overlay with grid-scoped loading, defer
  hide via requestAnimationFrame to eliminate blank-frame gap
- Clean up gridLoadingOverlay in dispose() to prevent DOM leak
This commit is contained in:
Will Miao
2026-06-24 21:11:13 +08:00
parent ea14d211be
commit 93ad81ed87
3 changed files with 56 additions and 2 deletions

View File

@@ -657,6 +657,9 @@ export class VirtualScroller {
this.resizeObserver.disconnect();
}
// Remove any active grid loading overlay
this.hideGridLoading();
// Remove rendered elements
this.clearRenderedItems();
@@ -1130,4 +1133,30 @@ export class VirtualScroller {
index: targetIndex
};
}
/**
* Show a grid-scoped loading indicator (replaces full-page overlay)
* Only covers the card grid area, leaving header/sidebar unaffected.
*/
showGridLoading() {
// Remove any stale overlay from a prior deferred hide (e.g. from final rAF)
this.hideGridLoading();
const overlay = document.createElement('div');
overlay.className = 'grid-loading-overlay';
const spinner = document.createElement('div');
spinner.className = 'loading-spinner';
overlay.appendChild(spinner);
this.gridElement.appendChild(overlay);
this.gridLoadingOverlay = overlay;
}
/**
* Hide the grid-scoped loading indicator.
*/
hideGridLoading() {
if (this.gridLoadingOverlay) {
this.gridLoadingOverlay.remove();
this.gridLoadingOverlay = null;
}
}
}