Search code examples
event-handlingdom-eventsblazorblazor-webassembly

Listen to keyboard input in the whole Blazor page


I'm trying to implement a Blazor app that listens to keyboard input all the time (some kind of full screen game, let's say).

I can think of a key down event listener as a possible implementation for it, since there's not really an input field to auto-focus on.

Is there a better solution to just react to key-presses in any part of the screen?

In case that's the chosen one, how can I add an event listener from a client-side Blazor app? I've failed trying to do so by having a script like this:

EDIT: I modified a little bit the code below to actually make it work after fixing the original, key mistake that I was asking about.

scripts/event-listener.js

window.JsFunctions = {
    addKeyboardListenerEvent: function (foo) {
        let serializeEvent = function (e) {
            if (e) {
                return {
                    key: e.key,
                    code: e.keyCode.toString(),
                    location: e.location,
                    repeat: e.repeat,
                    ctrlKey: e.ctrlKey,
                    shiftKey: e.shiftKey,
                    altKey: e.altKey,
                    metaKey: e.metaKey,
                    type: e.type
                };
            }
        };

        // window.document.addEventListener('onkeydown', function (e) { // Original error
        window.document.addEventListener('keydown', function (e) {
            DotNet.invokeMethodAsync('Numble', 'JsKeyDown', serializeEvent(e))
        });
    }
};

index.html

<head>
    <!--  -->
    <script src="scripts/event-listener.js"></script>
</head>

Invoking it through:

protected async override Task OnAfterRenderAsync(bool firstRender)
{
    await jsRuntime.InvokeVoidAsync("JsFunctions.addKeyboardListenerEvent");
}

and having the following method trying to receive the events:

using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;

namespace Numble;

public static class InteropKeyPress
{
    [JSInvokable]
    public static Task JsKeyDown(KeyboardEventArgs e)
    {
        Console.WriteLine("***********************************************");
        Console.WriteLine(e.Key);
        Console.WriteLine("***********************************************");

        return Task.CompletedTask;
    }
}

I manage to get the script executed, but I'm not receiving any events.


Solution

  • The name of the event is keydown, not onkeydown.