Blazor에서 Javascript Interop을 사용하여 테마 전환

· 3분 읽기

웹 페이지를 열 때마다 플래시백으로 인해 어려움을 겪는 저와 같은 사람들을 위해 Javascript를 사용하여 밝은 모드와 어두운 모드 사이를 전환하고 Javascript Interop을 사용하여 Blazor에서 호출하는 방법에 대한 매우 간단한 솔루션을 제시했습니다.

부모 속성 설정

우선, 식별자로 상위 요소를 식별해야 합니다. 이는 해당 식별자의 값에 따라 색상을 변경하기 때문입니다.

Javascript에서 이를 수행하려면 다음 명령을 실행해야 합니다.

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

우리의 경우 각 스타일 유형에 대해 lightdark라는 두 개의 식별자를 갖고 싶습니다.

로직을 처리하기 위한 자바스크립트 파일 생성

이제 식별자를 업데이트하는 기능이 생겼습니다. 이제 해당 로직을 실행하는 기능을 사용하여 Javscript 파일을 만들어 보겠습니다. 파일 이름은 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로 언제든지 저에게 연락해 주세요(트위터에서는 실제로 @emimontesdeocaa이고 끝에 두 개의 aa가 있습니다). 블로그 헤더에서 내 소셜 미디어의 대부분을 찾을 수도 있습니다.

게시물이 마음에 드셨기를 바랍니다!

리소스