在 Blazor 中使用 Javascript Interop 切换主题
对于像我这样每次打开网页时都会出现闪回的人,我想出了一个超级简单的解决方案,介绍如何使用 Javascript 在浅色和深色模式之间切换,并使用 Javascript Interop 从 Blazor 调用它。
设置父属性
首先,我们必须使用标识符来标识父元素,这是因为我们根据该标识符的值更改颜色。
为了在 Javascript 中做到这一点,我们必须运行这个命令
document.documentElement.setAttribute('data-theme', 'YOUR_IDFENTIFIER');
在我们的例子中,我们希望每种样式都有两个标识符,分别是 light 和 dark。
创建 Javascript 文件来处理逻辑
现在我们有了更新标识符的函数,现在让我们创建一个包含运行该逻辑的函数的 Javscript 文件。我们的文件将被称为 app.js

在该文件中,我们将有一个函数来调用我们之前提到的代码。
var toggleTheme = function (identifier) {
document.documentElement.setAttribute('data-theme', identifier);
}
将 Javascript 文件添加到 Blazor
通过将脚本添加到脚本所在的位置,将脚本添加到 Blazor 应用程序。
<script src="~/js/app.js"></script>
创建服务
现在我们有了 Javascript 代码,我们需要创建一个名为 ThemeToggleService 的服务。

该服务将处理在 light 和 dark 主题之间切换的逻辑。
注入 JSInterop
为了调用任何 Javascipt,我们必须调用 JSInterop,因此我们必须创建一个将注入的属性。
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace BlazorDarkmodeToggle.Data
{
private readonly IJSRuntime jSRuntime;
public ThemeToggleService(IJSRuntime jSRuntime)
{
this.jSRuntime = jSRuntime;
}
}
设置标识符的函数
现在我们已经创建了服务,让我们创建设置标识符的函数,该函数将只更新页面中的 data-theme。
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace BlazorDarkmodeToggle.Data
{
public class ThemeToggleService
{
private readonly IJSRuntime jSRuntime;
public ThemeToggleService(IJSRuntime jSRuntime)
{
this.jSRuntime = jSRuntime;
}
public bool IsLightTheme { get; set; } = true;
public string GetIdentifier => IsLightTheme ? "light" : "dark";
public async Task ToggleTheme() {
IsLightTheme = !IsLightTheme;
await jSRuntime.InvokeVoidAsync("toggleTheme", GetIdentifier);
}
}
}
添加服务启动
为了使该服务可用于所有组件和页面,我们必须将其添加到 Program.cs 文件中。
builder.Services.AddSingleton<ThemeToggleService>();
所以文件最终会是这样的
using BlazorDarkmodeToggle.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddSingleton<ThemeToggleService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
请记住,这可能会发生变化,具体取决于您使用的是 Blazor Server 还是 Blazor WebAssembly。
烘焙 CSS
现在我们已经准备好了部分代码,我们必须开始处理 CSS。我们要做的就是将所有处理 css 颜色、背景等的 css 属性设置为一个变量。
:root {
--background-color:#ffffff;
--text-color:#000000;
}
完成此操作后,使用标识符,我们可以轻松地在标识符之间进行更改,并且它将使用其他值之一。
[data-theme="dark"] {
--background-color: #000000;
--text-color: #ffffff;
}
对于很酷的动画淡入淡出,我们只需为所有属性添加一个 transition 属性,这样看起来就不错了。
* {
transition: all 250ms;
}
现在我们将这个变量分配给一些CSS类,这样我们就可以在Blazor页面上看到它们。
.app-background {
background-color: var(--background-color);
width: 200px;
height: 200px;
}
.app-text {
color: var(--text-color);
}
请记住通过将文件添加到 head 上来将其添加到 Blazor 应用程序。
<link href="css/app.css" rel="stylesheet" />
从 Blazor 调用
那么我们要如何测试呢?为了简单起见,我们只需添加一个带有 app-background 类的 div,并且在其内部将有一个 p 和 app-text 类。因此,让我们在 Pages 文件夹下创建一个名为 Theme.razor 的页面,并为其添加一些代码
@page "/theme"
@using BlazorDarkmodeToggle.Data
@inject ThemeToggleService ThemeToggleService
<button class="btn btn-primary" @onclick=Toggle>Toggle theme</button>
<br />
<div class="app-background">
<p class="app-text">Hello world!</p>
</div>
@code{
public async Task Toggle()
{
await this.ThemeToggleService.ToggleTheme();
}
}
我们可以通过转到 /theme 来测试这一点,但我们也将其添加到导航栏
<div class="nav-item px-3">
<NavLink class="nav-link" href="theme">
<span class="oi oi-list-rich" aria-hidden="true"></span> Theme togle
</NavLink>
</div>
测试

正如您所看到的,一旦我们切换主题、背景和字体颜色更改,现在您就可以看到它有多么强大,如果您实际上在 CSS 上使用此变量开发整个页面,您可以拥有不同的主题,只需切换它们即可!
太棒了!
代码
整个项目都在 Github 上,您可以在此处找到它!
如果您有任何问题或疑问,请随时在任何社交媒体上与我联系:@emimontesdeoca(在 Twitter 中实际上是 @emimontesdeocaa,末尾有两个 aa)。您还可以在博客标题上找到我的大部分社交活动。
希望你喜欢这篇文章!