Search code examples
javascripthtmlblazorblazor-webassembly

Call Javascript directly from Blazor "HTML" section


A .razor component file is defined with a "HTML" section, in which you can define the HTML of your component, and a @code {} section in which C# code can be written to add logic to the component.

I know that you can call JS methods from the C# code in the @code {} section, but what I cannot find anywhere is if there's any way to call those JS functions from the "HTML" part directly like

<button onclick="a_js_function()">click me</button> 

as that would be much nicer to write and read.

Alternatively, I'd like to know if it's at all possible to somehow refer to regular HTML with JS from a Blazor PWA. Thanks!

"why use Blazor then?" -> I don't have a choice :)

Edit: making globally available JS functions is not desirable either.

Clarifications

Since I'm seeing much criticism, I'm adding an example of how it could look:

@inject IJSRuntime JS

<button @onclick=module.a_js_function>click me<button/>

@code {
    IJSObjectReference module;

    protected override async Task OnAfterRenderAsync(bool firstRender) {
        module = await JS.InvokeAsync<IJSObjectReference>(
                "import", "./Pages/Component.razor.js");

    }
}

I know that this doesn't work, but since Blazor allows me to call globally available JS and write an isolated JS module that is scoped to my component, I was thinking there might be a way to somehow combine both and call scoped JS from the HTML section of the Blazor component.

I think this is a legitimate interrogation, and the fact that it is not possible is not a reason to have it closed.


Solution

  • Το call scoped JS from the HTML section of the Blazor component you can do the following:

    @implements IAsyncDisposable
    @inject IJSRuntime JS
    
    <button @onclick="@(() => _module.InvokeVoidAsync("a_js_function"))">click me</button>
    
    @code {
        IJSObjectReference _module;
    
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                _module = await JS.InvokeAsync<IJSObjectReference>(
                    "import", "./Pages/Component.razor.js");
            }
        }
    
        public async ValueTask DisposeAsync()
        {
            if (_module != null)
            {
                await _module.DisposeAsync();
            }
        }
    }