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

.NET 8 Blazor路由切换时如何调用JS函数并保留样式?

解决方案

方法1:在JS中监听Blazor路由导航事件并复用样式表

先优化updateMood函数,避免重复创建样式表;同时监听Blazor内置的路由完成事件,确保路由切换时重新应用主题:

function updateMood() {
  // 移除已存在的主题样式表,防止重复添加
  const existingLink = document.querySelector('link[href*="mood.css"]');
  if (existingLink) {
    existingLink.remove();
  }

  const linkElement = document.createElement('link');
  linkElement.rel = 'stylesheet';
  linkElement.type = 'text/css';
  const appMood = localStorage.getItem('appmood');
  linkElement.href = appMood === "dark" ? 'css/darkmood.css' : 'css/lightmood.css';
  document.head.appendChild(linkElement);
}

// 页面初始加载时执行
document.addEventListener('DOMContentLoaded', updateMood);
// 监听Blazor路由切换完成事件
document.addEventListener('blazornavigationfinished', updateMood);

blazornavigationfinished是Blazor内置的事件,无论服务器还是WebAssembly渲染模式都会触发,完全在JS层面处理,不会影响非交互式页面。

方法2:通过全局布局组件条件调用JS

在全局布局(如MainLayout.razor)中添加逻辑,仅在交互式渲染模式下调用JS,避开非交互式页面的限制:

@inherits LayoutComponentBase
@inject IJSRuntime JSRuntime

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            @Body
        </article>
    </main>
</div>

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 仅在交互式模式下执行JS调用,非交互式页面自动跳过
        if (IsInteractiveServer || IsInteractiveWebAssembly)
        {
            await JSRuntime.InvokeVoidAsync("updateMood");
        }
        await base.OnAfterRenderAsync(firstRender);
    }
}

全局布局会作用于所有页面,无需在每个页面单独编写逻辑,同时通过模式判断避免了非交互式页面调用JS的问题。

方法3:改用CSS类切换替代动态样式表

放弃动态添加样式表的方式,通过切换根元素的类来控制主题,这种方式不会因路由切换丢失样式:

  1. 在wwwroot/css/site.css中定义主题变量:
:root.light {
    --bg-color: #ffffff;
    --text-color: #333333;
    /* 其他浅色主题样式变量 */
}

:root.dark {
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
    /* 其他深色主题样式变量 */
}
  1. 修改JS函数切换根元素类:
function updateMood() {
  const root = document.documentElement;
  const appMood = localStorage.getItem('appmood');
  root.classList.remove('light', 'dark');
  root.classList.add(appMood === "dark" ? 'dark' : 'light');
}

document.addEventListener('DOMContentLoaded', updateMood);
document.addEventListener('blazornavigationfinished', updateMood);

这种方式更高效,且样式状态不会因Blazor路由操作丢失。


内容的提问来源于stack exchange,提问作者Robin Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:24:56