Blazor の Javascript Interop を使用してテーマを切り替える

· 2分で読める

Web ページを開くたびにフラッシュバックに悩まされている私のような人のために、JavaScript を使用してライト モードとダーク モードを切り替え、JavaScript Interop を使用して Blazor から呼び出す方法に関する非常に簡単な解決策を思いつきました。

親属性の設定

まず第一に、親要素を識別子で識別する必要があります。これは、その識別子の値に応じて色を変更するためです。

これを Javascript で行うには、次のコマンドを実行する必要があります。

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

この場合、スタイルのタイプごとに lightdark という 2 つの識別子が必要になります。

ロジックを処理するための Javascript ファイルの作成

識別子を更新する関数ができたので、そのロジックを実行する関数を含む Javascript ファイルを作成しましょう。私たちのファイルは app.js という名前になります

このファイルには、前に説明したコードを呼び出す関数が含まれます。

var toggleTheme = function (identifier) {
    document.documentElement.setAttribute('data-theme', identifier);
}

Blazor への Javascript ファイルの追加

スクリプトが配置されている場所にスクリプトを追加して、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 を追加するだけで、その中に app-text クラスの p が含まれます。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 が 2 つ付いています)。私のソーシャルのほとんどはブログのヘッダーからも見つけることができます。

投稿が気に入っていただければ幸いです!

リソース