Call JavaScript from Blazor

Blazor WebAssembly: wwwroot/index.html

<!DOCTYPE html>
<html>

<head>
    <!-- ... ... ... -->
</head>

<body>

    <!-- ... ... ... -->
	
    <script src="_framework/blazor.webassembly.js"></script>
	
    <script src="js/foo.js"></script>
	
</body>

</html>

wwwroot/js/foo.js

window.barWindowObject = {

    bazz: function (elementId, width, height) {
	
        // ... ... ...
		
    },

    bax: function (...) {

        // ... ... ...
    }
}

Javascript.cs

using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FooNameSpace
{
    public static class Javascript
    {
        public static Task LoadAnimation(string elementId, int width, int height)
        {
            return JSRuntime.Current.InvokeAsync<object>("barWindowObject.bazz", elementId, width, height);
        }
    }
}

Pages/foo.cshtml

@page "/settings"
@inject FooService fs

// ... ... ...

<div id="fooDiv"></div>

@functions{
    
	// ... ... ...
	
    protected override void OnAfterRender()
    {
        base.OnAfterRender();
        Javascript.bazz("fooDiv", 1000, 200);
    }
}

Call Blazor from JavaScript

wwwroot/js/foo.js

window.barWindowObject = {

    bazz: function (elementId, width, height) {
	
        // ... ... ...
		
    },

    bax: function (...) {

        // ... ... ...
    }
}

Javascript.cs

using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FooNameSpace
{
    public static class Javascript
    {
	
		public static event Action FooEventHandler;
		
		// ... ... ...
		
        [JSInvokable]
        public static Task FireFooEvent()
        {
            return Task.Run(() => FooEventHandler?.Invoke());
        }
    }
}

Pages/foo.cshtml

@page "/settings"
@inject FooService fs
@implements IDisposable

// ... ... ...


<button id="fooBtn" onClick="barWindowObject.bax"></button>


@functions{
    
	// ... ... ...
	
    void OnFiredFooEvent()
    {
        //count++;
		
		// ... ... ...
		
        StateHasChanged();
    }
	
    protected override void OnAfterRender()
    {
        base.OnAfterRender();
        
        Javascript.FooEventHandler += OnFiredFooEvent;
    }

    public void Dispose()
    {
        Javascript.FooEventHandler -= OnFiredFooEvent;
    }
}

<script>
window.barWindowObject = {

    // ... ... ...
	
    bax: function (...) {

        // ... ... ...
		
        // when some condition met
        DotNet.invokeMethodAsync("FooNameSpace", "FireFooEvent");
    }
}
</script>