تبديل السمات باستخدام Javascript Interop في Blazor

· 4 دقيقة قراءة

بالنسبة للأشخاص مثلي الذين يعانون من ذكريات الماضي في كل مرة أفتح فيها صفحة ويب، فقد توصلت إلى حل بسيط للغاية حول كيفية التبديل بين الوضع الفاتح والوضع الداكن باستخدام Javascript واستدعائه من Blazor باستخدام Javascript Interop.

تحديد السمة الأصل

بادئ ذي بدء، يتعين علينا تحديد العنصر الأصلي بمعرف، وذلك لأننا نغير الألوان اعتمادًا على قيمة ذلك المعرف.

وللقيام بذلك في Javascript، سيتعين علينا تشغيل هذا الأمر

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

في حالتنا، نريد أن يكون لدينا معرفان لكل نوع من الأنماط، وهما light و dark.

إنشاء ملف جافا سكريبت للتعامل مع المنطق

لدينا الآن وظيفة تحديث المعرف، والآن لنقم بإنشاء ملف Javascript بوظيفة تقوم بتشغيل هذا المنطق. سيتم استدعاء ملفنا app.js

في هذا الملف، سيكون لدينا وظيفة تستدعي الكود الذي ذكرناه سابقًا.

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

إضافة ملف جافا سكريبت إلى 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);
}

تذكر إضافة الملف إلى تطبيق Blazor عن طريق إضافته على head.

<link href="css/app.css" rel="stylesheet" />

اتصال من بليزر

إذن كيف سنختبر هذا؟ لتبسيط الأمر، سنقوم فقط بإضافة 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 في النهاية). يمكنك أيضًا العثور على معظم وسائل التواصل الاجتماعي الخاصة بي على رأس المدونة.

آمل أن تكونوا قد أحببت هذا المنصب!

الموارد