【发布时间】:2022-03-25 02:33:11
【问题描述】:
我有一个可无限滚动的应用(SPA 网站)feed。到达页面底部时 - 加载了一组新数据。
问题是当从一个页面导航到另一个页面时 - 而不是立即切换上下文 - blazor 在新页面上平滑滚动到 0 滚动位置。
这会导致各种问题。
- 从提要(我滚动了一下)切换到其他页面时 - 这也会触发页面数据加载功能的提要结束
- 当从其他页面(我滚动一点)切换到 feed -
blazor再次平滑滚动到 0 位置,并且它还触发数据加载功能,因为在页面加载时 - 滚动位置已经被认为在新页面的底部..
我尝试做的是实现IAsyncDisposable 和/或IDisposable,但似乎不能保证在到达新页面之前执行Dispose 方法!
在我的测试中,我试图在离开页面之前将窗口滚动位置设置为 0:
public async ValueTask DisposeAsync()
{
_data?.Clear();
_data= null;
((IJSInProcessRuntime)_jsRuntime).InvokeVoid($"setScrollPosition", 0);
}
js
function setScrollPosition(scrollPosition) {
window.scrollTo({ top: scrollPosition, left: 0, behavior: 'instant' })
}
这不起作用,因为新页面在旧页面被处理之前被初始化。
到达 feed 页面底部时负责数据加载的代码是:
protected override async Task OnInitializedAsync()
{
InitEndOfPageDetection();
await LoadMoreDataAsync();
}
private async Task LoadMoreDataAsync()
{
var response = await Http.GetFromJsonAsync<<MoreData>($"Feed/GetMoreData");
var data = response.Data;
_data.AddRange(data);
_isEndOfPageReached = data.Count == 0;
StateHasChanged();
}
private DotNetObjectReference<ViewFeed> objRef;
public void InitEndOfPageDetection()
{
objRef = DotNetObjectReference.Create(this);
((IJSInProcessRuntime)JSRuntime).InvokeVoid("initEndOfPageDetector", objRef);
}
object _lock = new object();
bool _isEndOfPageReached = false;
[JSInvokable]
public void EndOfPageReached()
{
lock (_lock)
{
if (_isEndOfPageReached)
{
return;
}
_isEndOfPageReached = true;
LoadMoreDataAsync();
}
}
js
function isEndOfPage() {
var tresholdPx = 300;
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - tresholdPx) {
return true;
}
return false;
}
function initEndOfPageDetector(instance) {
window.onscroll = function (ev) {
if (isEndOfPage()) {
instance.invokeMethodAsync('EndOfPageReached');
}
};
}
如前所述 - 不幸的是,新页面的内容是在前一页被处理之前加载的,所以我的滚动到 0 位置的hack 不起作用.. 注意:出于演示目的,我对代码进行了一些简化。请求查询参数丢失等。
我希望立即切换到新页面,而无需滚动或任何其他类型的黑客攻击。有没有办法在Blazor 中本地实现这一点?这是否是其他 SPA 框架(例如 Angular 和 ReactJs)在切换页面上下文时默认的行为方式?
我正在使用.Net 5 和Blazor WASM 模板。
【问题讨论】:
标签: asp.net-core blazor asp.net-core-5.0