.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类切换替代动态样式表
放弃动态添加样式表的方式,通过切换根元素的类来控制主题,这种方式不会因路由切换丢失样式:
- 在
wwwroot/css/site.css中定义主题变量:
:root.light { --bg-color: #ffffff; --text-color: #333333; /* 其他浅色主题样式变量 */ } :root.dark { --bg-color: #1a1a1a; --text-color: #ffffff; /* 其他深色主题样式变量 */ }
- 修改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
相关产品推荐
相关产品推荐

