如何在 Blazor Server 应用中实现锚点导航(跳转到页面内指定元素)

13次阅读

如何在 Blazor Server 应用中实现锚点导航(跳转到页面内指定元素)

blazor server 默认不支持 url 片段(如 `#section2`)自动滚动至对应 id 元素,因为组件渲染异步发生,浏览器原生锚点行为在初始 dom 加载时失效;需结合 javascript 与 `navigationmanager` 监听路由变化,手动触发 `scrollintoview`。

在 Blazor Server 应用中,直接使用 无法触发预期的页面内滚动——点击后 URL 正确变为 /test#section2,但浏览器仍停留在页面顶部。根本原因在于:Blazor Server 是单页应用(SPA),页面并非传统 html 全量重载,而是通过 SignalR 增量渲染组件;当浏览器解析 URL 片段时,目标元素尚未存在于 DOM 中,导致原生锚点滚动机制失效。

解决此问题的核心思路是:路由位置变更(包括哈希变化)且组件完成渲染后,主动提取 URL 中的 fragment(即 #xxx 部分),通过 jsRuntime 调用 javaScript 方法查找并平滑滚动到对应 ID 元素。

✅ 推荐实现方案

1. 创建可复用的 AnchorNavigation.razor 组件

将以下代码保存为 Components/AnchorNavigation.razor:

@inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager @implements IDisposable  @code {     protected override void OnInitialized()     {         NavigationManager.LocationChanged += OnLocationChanged;     }      protected override async Task OnAfterRenderAsync(bool firstRender)     {         await ScrollToFragment();     }      public void Dispose()     {         NavigationManager.LocationChanged -= OnLocationChanged;     }      private async void OnLocationChanged(object sender, LocationChangedEventArgs e)     {         await ScrollToFragment();     }      private async Task ScrollToFragment()     {         var uri = new Uri(NavigationManager.Uri, UriKind.Absolute);         var fragment = uri.Fragment;         if (fragment.StartsWith('#'))         {             // 兼容文本片段(Text Fragments API,如 #target:~:text=xxx)             var elementId = fragment.Substring(1);             var textFragmentIndex = elementId.IndexOf(":~:", StringComparison.Ordinal);             if (textFragmentIndex > 0)                 elementId = elementId.Substring(0, textFragmentIndex);              if (!string.IsNULLOrWhiteSpace(elementId))                 await JSRuntime.InvokeVoidAsync("BlazorScrollToId", elementId);         }     } }

✅ 优势:组件自动订阅路由事件、自动清理资源(IDisposable)、兼容 Text Fragments API、仅在必要时执行滚动。

2. 注册全局 javascript 函数

在 _Host.cshtml(Server)或 index.html(wasm)的

中、

⚠️ 关键注意:必须置于 Blazor 脚本之前,否则 BlazorScrollToId 在 JSRuntime 调用时未定义。

3. 在页面或布局中使用

  • 方式一(局部启用):在需要锚点跳转的 .razor 页面底部添加:
  • 方式二(全局启用):将其放入 Sha

text=ZqhQzanResources