【问题标题】:Preventing blazors smooth page scroll when navigating to new page导航到新页面时防止 blazors 平滑页面滚动
【发布时间】: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 框架(例如 AngularReactJs)在切换页面上下文时默认的行为方式?

我正在使用.Net 5Blazor WASM 模板。

【问题讨论】:

    标签: asp.net-core blazor asp.net-core-5.0


    【解决方案1】:

    style="height:100vh; overflow-y:scroll;" 添加到_Host.cshtml 中的&lt;app&gt;&lt;/app&gt; 标记。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    相关资源
    最近更新 更多