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
相关产品推荐
相关产品推荐

