You need to enable JavaScript to run this app. Blazor WebAssembly中Razor页面如何访问body标签并修改其类属性?
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 05:54:04