.NET MAUI Blazor - アプリ起動時に要素にJavaScriptのイベントを付与する方法のアイキャッチ画像

.NET MAUI Blazor – アプリ起動時に要素にJavaScriptのイベントを付与する方法

.NET MAUI BlazorでJavaScriptを利用して要素にイベント付与する方法を紹介していきます。

要素にイベント付与が行えるとタップイベントなどが実行できるため実装の幅を広げることができます。

はじめに

.NET MAUI BlazorでJavaScriptを読み込む方法はMicrosoftで紹介されています。本記事では、JavaScriptを読み込んだ際に要素にイベント付与する方法を紹介していきます。

読み込むJavaScriptは「wwwroot/js/app.js」にします。

参考にしたMicrosoftの記事は以下になります。

「wwwroot/index.html」を利用する方法

「wwwroot/index.html」を利用する場合、Blazor スクリプトを利用します。Blazor スクリプトは「_framework/blazor.webview.js」より後に記載してください。前に記載するとBlazor スクリプトが実行されません。

次の例は「<script src=”js/app.js”></script>」を配置して「wwwroot/js/app.js」を読み込んでいます。

    <script src="_framework/blazor.webview.js" autostart="false"></script>
    <!-- ここから -->
    <script>
        Blazor.start().then(function () {
            var customScript = document.createElement('script');
            customScript.setAttribute('src', 'js/app.js');
            document.head.appendChild(customScript);
        });
    </script>
    <!-- ここまでを -->

この方法を利用する場合、JavaScript側を工夫する必要がありません。次の例は、ID:btn_sampleをクリックされたときにsampleクラスを赤文字にしています。

const btnSampleElem = document.getElementById("btn_sample");

btnSampleElem.addEventListener("click", () => {
    const sampleClassElems = document.getElementsByClassName("sample");
    for (const elemItem of sampleClassElems) {
        elemItem.style.color = "red";
    }
});

ちなみに

Blazor スクリプト完了後にイベント付与を行えばいいため、次の例のようにすればapp.jsで完結すると考えるのではないでしょうか。しかし、この方法ではイベント付与が行えません。

Blazor.start().then(function () {
    const btnSampleElem = document.getElementById("btn_sample");

    btnSampleElem.addEventListener("click", () => {
        const sampleClassElems = document.getElementsByClassName("sample");
        for (const elemItem of sampleClassElems) {
            elemItem.style.color = "red";
        }
    });
});

その理由は、次の通りになります。

次の画像はイベント付与のタイミングを図で表しています。app.jsで完結するとページコンテンツを読み込む前にイベント付与が行われます。そのため、ページコンテンツにイベント付与が行えなくなります。

app.jsでイベント付与できない理由
app.jsで完結するとき
scriptタグ作成後にapp.jsを読み込むとイベント付与できる理由
scriptタグ生成後にapp.jsを読み込むとき

@codeに記載する方法

razorを利用した方法になります。JavaScriptを読み込むためには以下の内容を追加します。イベント付与には21行目を利用します。

<!-- ここから -->
@implements IAsyncDisposable
@inject IJSRuntime JS
<!-- ここまでを -->

@page "/"

<div class="sample">テキスト</div>
<button id="btn_sample">クリック</button>

<!-- ここから -->
@code {
    private IJSObjectReference module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import", "./js/app.js");
            // ここでイベント付与を行う。
            await module.InvokeVoidAsync("Initialized");
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            await module.DisposeAsync();
        }
    }
}
<!-- ここまでを -->

この方法を利用する場合、JavaScriptのexport宣言を利用する必要があります。メソッド名はInvokeVoidAsyncメソッドの引数と合わせる必要があります。

次の例では「await module.InvokeVoidAsync(“Initialized”);」と宣言していますので、メソッド名は「Initialized」としています。

export function Initialized() {
    const btnSampleElem = document.getElementById("btn_sample");

    btnSampleElem.addEventListener("click", () => {
        const sampleClassElems = document.getElementsByClassName("sample");
        for (const elemItem of sampleClassElems) {
            elemItem.style.color = "red";
        }
    });
}

おわりに

本記事では2種類の方法を紹介してきましたが、おすすめの方法は「@codeに記載する方法」になります。

「「wwwroot/index.html」を利用する方法」の場合、複数のページで対応することが困難になります。しかし、「@codeに記載する方法」の場合、ページごとにJavaScriptを読み込めるため複数ページの対応ができます。

本記事で紹介した方法を利用して様々なアプリを作成していきたいと思います。

.NET MAUI Blazorの記事は、他にも記載しています。よければ参考にしてください!!