Переключение тем с помощью Javascript Interop в Blazor
Для таких людей, как я, которые страдают от воспоминаний каждый раз, когда я открываю веб-страницу, я придумал очень простое решение, как переключаться между светлым и темным режимами с помощью Javascript и вызывать его из Blazor с помощью Javascript Interop.
Установка родительского атрибута
Прежде всего, мы должны идентифицировать родительский элемент с помощью идентификатора, потому что мы меняем цвета в зависимости от значения этого идентификатора.
Чтобы сделать это в Javascript, нам нужно будет запустить эту команду
[[[ТОК_1]]]
В нашем случае мы хотим иметь два идентификатора для каждого типа стиля: light и dark.
Создание файла Javascript для обработки логики
Теперь у нас есть функция для обновления идентификатора, теперь давайте создадим файл Javscript с функцией, которая выполняет эту логику. Наш файл будет называться app.js

В этом файле у нас будет функция, которая будет вызывать код, о котором мы упоминали ранее.
[[[ТОК_6]]]
Добавление файла Javascript в Blazor
Добавьте сценарий в приложение Blazor, добавив его туда, где расположены сценарии.
[[[ТОК_7]]]
Создание сервиса
Теперь, когда у нас есть код Javascript, нам нужно создать сервис, который будет называться ThemeToggleService.

Этот сервис будет обрабатывать логику переключения между темами light и dark.
Внедрение JSInterop
Чтобы вызвать любой Javascipt, нам нужно вызвать JSInterop, поэтому нам нужно создать свойство, которое будет выполнять внедрение.
[[[ТОК_12]]]
Функция для установки идентификатора
Теперь, когда у нас есть служба, давайте создадим функцию для установки идентификатора. Эта функция будет просто обновлять 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);
}
Не забудьте добавить файл в приложение Blazor, добавив его в head.
<link href="css/app.css" rel="stylesheet" />
Звонок от Blazor
Итак, как мы собираемся это проверить? Для простоты мы просто добавим элемент div с классом app-background и внутри него будет p с классом app-text.Итак, давайте создадим страницу с именем Theme.razor в папке Pages и добавим для нее немного кода.
@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 (в Твиттере на самом деле это @emimontesdeocaa с двумя aa в конце). Большую часть моих соцсетей вы также можете найти в шапке блога.
Надеюсь, вам понравился пост!