You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor WASM中表格滚动位置的获取与设置方法

Blazor表格组件滚动位置保存与恢复实现方案

问题分析

你尝试用onfocusout捕获导航离开时的滚动位置,但div默认不是可聚焦元素,因此该事件不会触发。正确的做法是利用Blazor的导航事件和DOM操作来实现滚动位置的保存与恢复。

具体实现步骤

1. 获取滚动容器引用

修改表格容器div,添加@ref来获取DOM元素引用:

<div class="table-wrap" @ref="tableWrapElement">
    <!-- 原有表格代码保持不变 -->
</div>

在组件代码块中定义变量并注入依赖:

@inject NavigationManager NavigationManager
@inject IJSRuntime JSRuntime
@implements IDisposable

@code {
    private ElementReference tableWrapElement;
    private (double ScrollX, double ScrollY) _savedScrollPosition;
    private const string _storageKey = "TableScroll_ReportComponent"; // 唯一标识,避免存储冲突

2. 导航离开时保存滚动位置

通过NavigationManager的LocationChanged事件,在导航离开当前组件时捕获并保存滚动位置到本地存储:

protected override void OnInitialized()
    {
        NavigationManager.LocationChanged += OnNavigationChanged;
        base.OnInitialized();
    }

    private async void OnNavigationChanged(object sender, LocationChangedEventArgs e)
    {
        // 验证是否为离开当前页面的导航
        if (!e.Location.Contains(NavigationManager.Uri))
        {
            // 获取当前滚动位置
            var scrollX = await JSRuntime.InvokeAsync<double>("getElementScrollLeft", tableWrapElement);
            var scrollY = await JSRuntime.InvokeAsync<double>("getElementScrollTop", tableWrapElement);
            
            // 序列化后保存到LocalStorage
            await JSRuntime.InvokeVoidAsync("localStorage.setItem", _storageKey, 
                System.Text.Json.JsonSerializer.Serialize((scrollX, scrollY)));
        }
    }

3. 组件加载时恢复滚动位置

在组件首次渲染完成后,从本地存储读取之前保存的位置并恢复:

protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 读取保存的滚动位置
            var savedJson = await JSRuntime.InvokeAsync<string>("localStorage.getItem", _storageKey);
            if (!string.IsNullOrEmpty(savedJson))
            {
                _savedScrollPosition = System.Text.Json.JsonSerializer.Deserialize<(double, double)>(savedJson);
                // 恢复滚动位置
                await JSRuntime.InvokeVoidAsync("setElementScrollPosition", tableWrapElement, 
                    _savedScrollPosition.ScrollX, _savedScrollPosition.ScrollY);
            }
        }
        await base.OnAfterRenderAsync(firstRender);
    }

4. 清理订阅与添加JS辅助函数

实现IDisposable接口取消事件订阅,避免内存泄漏:

public void Dispose()
    {
        NavigationManager.LocationChanged -= OnNavigationChanged;
    }
}

在项目的wwwroot/index.html(或组件内的<script>标签)中添加以下JS辅助函数:

// 获取元素水平滚动位置
function getElementScrollLeft(element) {
    return element.scrollLeft;
}

// 获取元素垂直滚动位置
function getElementScrollTop(element) {
    return element.scrollTop;
}

// 设置元素滚动位置
function setElementScrollPosition(element, scrollX, scrollY) {
    element.scrollLeft = scrollX;
    element.scrollTop = scrollY;
}

关键注意点

  • 使用LocalStorage保存位置可跨页面刷新保留,若仅需会话内保留,可替换为sessionStorage。
  • 确保_storageKey的唯一性,避免与其他组件的存储数据冲突。
  • 服务器端Blazor场景下,若依赖服务器状态,可将滚动位置保存到Session或全局状态服务中。

内容的提问来源于stack exchange,提问作者Cincy Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:58:10