在 Blazor 中使用 Javascript Interop 切换主题

· 2 分钟阅读

对于像我这样每次打开网页时都会出现闪回的人,我想出了一个超级简单的解决方案,介绍如何使用 Javascript 在浅色和深色模式之间切换,并使用 Javascript Interop 从 Blazor 调用它。

设置父属性

首先,我们必须使用标识符来标识父元素,这是因为我们根据该标识符的值更改颜色。

为了在 Javascript 中做到这一点,我们必须运行这个命令

document.documentElement.setAttribute('data-theme', 'YOUR_IDFENTIFIER');

在我们的例子中,我们希望每种样式都有两个标识符,分别是 lightdark

创建 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 的服务。

该服务将处理在 lightdark 主题之间切换的逻辑。

注入 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,并且在其内部将有一个 papp-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)。您还可以在博客标题上找到我的大部分社交活动。

希望你喜欢这篇文章!

资源