bind to document mouseup event on mousedown of a button in blazor

Viewed 621

I'm trying to do in blazor the equivalent of js code:

btn1.on('mousedown', function(){
    console.log('start');
    $(document).one('mouseup', function(){
       console.log('stop');
    });
});

is this possible in Blazor, without js interop ?

I bind the mouseup on the document, so I can do a mousedown on the button after move the mouse away and do a mouseup on the document

1 Answers

You need JSInterop to handle off page mouseup.

Add a script file including the following functions - I believe it needs to be above the Blazor js file in your base html SPA startup page. Note you will need your assembly name. We provide functionality to turn it on and off as we need it, as we don't need it all the time.

window.blazor_setMouseUpEvent = function (show) {
    if (show) {
        window.addEventListener("mouseup", CallBlazorButtonMouseUp);
    }
    else {
        window.removeEventListener("mouseup", CallBlazorButtonMouseUp);
    }
}

function CallBlazorMouseUp(event) {
    DotNet.invokeMethodAsync("[YourAssemblyName]", "ButtonMouseUp");
}

An Index.razor page to demo.

When the user mousedowns, the event handler turns on the JS event handler, which then picks up the mouseup event from anywhere on the screen. It invokes ButtonMouseUp which invokes mouseUpAction, both static. The page instance registers JsMouseUp with mouseUpAction. JsMouseUp does it's business (in our case changing the button colour and writing to output), invokes StateHasChanged (the mouse and thus focus could be anywhere) and finally unregisters the js event handler.

@page "/"

@using System.Diagnostics

<button class="btn @buttoncolour" @onmousedown="(e) => OnButton(e)">Test Click</button>

@code {

    [Inject] private IJSRuntime _js { get; set; }

    [JSInvokable]
    public static Task ButtonMouseUp()
    {
        mouseUpAction?.Invoke();
        return Task.CompletedTask;
    }

    private static Action mouseUpAction;
    private string buttoncolour = "btn-success";

    protected override Task OnInitializedAsync()
    {
        mouseUpAction = JsMouseUp;
        return base.OnInitializedAsync();
    }

    private void OnButton(MouseEventArgs e)
    {
        SetMouseUp(true);
        Debug.WriteLine("Down");
        buttoncolour = "btn-danger";
    }

    private void JsMouseUp()
    {
        Debug.WriteLine("Up");
        buttoncolour = "btn-success";
        _ = InvokeAsync(StateHasChanged);
        SetMouseUp(false);
    }

    private void SetMouseUp(bool action)
    => _js.InvokeAsync<bool>("blazor_setMouseUpEvent", action);

}

enter image description here

Related