Blazor WebAssembly中Razor页面如何访问body标签并修改其类属性?
实现方案
Blazor WASM本身没有直接操作外部DOM元素的纯C#原生API,我们可以通过「全局状态服务+官方标准JS Interop封装」的方案实现:仅底层DOM操作调用封装好的JS接口,上层所有业务逻辑完全在C#侧完成,无需额外编写自定义JS代码,也不需要把body标签移入Razor组件,符合你的需求。
步骤1:创建全局主题状态服务
新建ThemeService.cs类,统一管理主题状态和body修改逻辑:
using Microsoft.JSInterop; public class ThemeService { // 对外暴露当前主题,所有页面都可读取 public string CurrentTheme { get; private set; } = "theme-dark"; // 主题变更通知事件,组件可订阅实现响应式更新 public event Action OnThemeChanged; private readonly IJSRuntime _jsRuntime; public ThemeService(IJSRuntime jsRuntime) { _jsRuntime = jsRuntime; } // 切换主题方法,全局可调用 public async Task ToggleThemeAsync() { CurrentTheme = CurrentTheme == "theme-dark" ? "theme-default" : "theme-dark"; // 调用官方JS互操作接口修改body的class属性 await _jsRuntime.InvokeVoidAsync("document.body.setAttribute", "class", CurrentTheme); OnThemeChanged?.Invoke(); } // 初始化页面加载时的主题 public async Task InitThemeAsync() { await _jsRuntime.InvokeVoidAsync("document.body.setAttribute", "class", CurrentTheme); } }
步骤2:注册服务到依赖注入容器
打开项目的Program.cs,添加服务注册代码:
// 其他代码保持不变,添加下面这行 builder.Services.AddScoped<ThemeService>(); await builder.Build().RunAsync();
步骤3:修改MainLayout.razor接入主题服务
替换你原有的MainLayout代码如下:
@inherits LayoutComponentBase @inject ThemeService ThemeService @implements IAsyncDisposable <div class="grid-wrapper sidebar-bg bg1"> <div id="theme-tab"> <div class="theme-tab-item switch-theme bg-white" @onclick="ToggleTheme" data-theme="theme-default" title="Light"></div> <div class="theme-tab-item switch-theme bg-dark" @onclick="ToggleTheme" data-theme="theme-dark" title="Dark"></div> </div> <NavMenu /> <SideBar /> <div class="main"> @Body </div> <Footer /> </div> @code { protected override async Task OnInitializedAsync() { // 订阅主题变更事件,触发布局自动重渲染 ThemeService.OnThemeChanged += StateHasChanged; // 页面加载时初始化主题 await ThemeService.InitThemeAsync(); } private async Task ToggleTheme() { await ThemeService.ToggleThemeAsync(); } // 组件销毁时取消订阅,避免内存泄漏 public ValueTask DisposeAsync() { ThemeService.OnThemeChanged -= StateHasChanged; return ValueTask.CompletedTask; } }
步骤4:其他页面访问/修改主题
只需要在对应页面注入ThemeService即可直接操作,示例代码:
@page "/testpage" @inject ThemeService ThemeService <h3>测试页面</h3> <p>当前生效主题:@ThemeService.CurrentTheme</p> <button @onclick="SwitchToLight">从当前页面切换到浅色主题</button> @code { private async Task SwitchToLight() { if (ThemeService.CurrentTheme != "theme-default") { await ThemeService.ToggleThemeAsync(); } } }
内容的提问来源于stack exchange,提问作者cbalakus
相关产品推荐
相关产品推荐

