.net core 如何使用blazor绑定文档事件

.net core 如何使用blazor绑定文档事件,.net-core,blazor,.net Core,Blazor,我试图在Blazor上编写一个简单的蛇游戏,但我找不到任何方法将我的事件绑定到文档上。 有机会在不同元素上绑定事件,例如div或input 例如: 其中public void按键indiv(UIKeyboardEventArgs ev) {..} 我想,javascript方法document.onkeydown=function(evt){} 我找到了几种解决此问题的方法: 1) 使用JS绑定并调用blazor代码(取自) document.onkeydown = function (evt

我试图在Blazor上编写一个简单的蛇游戏,但我找不到任何方法将我的事件绑定到文档上。
有机会在不同元素上绑定事件,例如divinput
例如:

其中
public void按键indiv(UIKeyboardEventArgs ev)
{..}

我想,javascript方法
document.onkeydown=function(evt){}
我找到了几种解决此问题的方法:
1) 使用JS绑定并调用blazor代码(取自)

document.onkeydown = function (evt) {
  evt = evt || window.event;
  DotNet.invokeMethodAsync('Test.ClientSide', 'JsKeyDown', evt.keyCode);

  //Prevent all but F5 and F12
  if (evt.keyCode !== 116 && evt.keyCode !== 123)
      evt.preventDefault();
};

document.onkeyup = function (evt) {
  evt = evt || window.event;
  DotNet.invokeMethodAsync('Test.ClientSide', 'JsKeyUp', evt.keyCode);

  //Prevent all but F5 and F12
  if (evt.keyCode !== 116 && evt.keyCode !== 123)
      evt.preventDefault();
};
在c#中,使用标记为[JSInvokable]的方法和事件实现一个静态类。
这项工作已经完成,但每次印刷都会导致严重的延迟
2) 这可以添加输入标记并在其上绑定事件
这将比上一个更快,但是:
-它主要看起来像哈克,然后是解决方案
-我们无法捕捉到许多动作,如向上/向下箭头

有没有直接绑定blazor文档事件的方法?
更新1:我创建了一个简单的项目,以便更好地解释我试图实现的目标
Snake有3个实现:
1) 纯js-这是预期的行为
2) 使用js和blazor-通过JsInterop从js代码调用blazor函数

3) 使用输入标记-在control Snake的输入标记上绑定事件

您可以直接将事件绑定到C#方法,只需使用所需的事件标记(onkeyup/onmousemove…)

@page/“
@功能{
void KeyUp(UIKeyboardEventArgs e)
{
控制台写入线(e键);
}
受保护的重写任务OnInitAsync()
{
返回Task.CompletedTask;
}
}

也许可以使用JsInterop向文档中添加一个事件侦听器,并为事件分配一个匿名函数,该函数使用偶数参数调用您的C#方法

例如,您的JsInterop.js:

document.addEventListener('onkeypress', function (e) {
    DotNet.invokeMethodAsync('Snake', 'OnKeyPress', serializeEvent(e))
});
为了避免一些怪癖,将事件序列化如下:

var serializeEvent = function (e) {
    if (e) {
        var o = {
            altKey: e.altKey,
            button: e.button,
            buttons: e.buttons,
            clientX: e.clientX,
            clientY: e.clientY,
            ctrlKey: e.ctrlKey,
            metaKey: e.metaKey,
            movementX: e.movementX,
            movementY: e.movementY,
            offsetX: e.offsetX,
            offsetY: e.offsetY,
            pageX: e.pageX,
            pageY: e.pageY,
            screenX: e.screenX,
            screenY: e.screenY,
            shiftKey: e.shiftKey
        };
        return o;
    }
};
在您的C#代码中,您将有:

[JSInvokable]
public static async Task OnMouseDown(UIMouseEventArgs e){
    // Do some stuff here
}

我和您有相同的需求,我使用invokeMethodAsync设法将文档事件(例如keydown)连接到我的Razor方法,但后来我发现,如果Razor方法更改绑定到HTML元素的某些状态,我就错过了Blazor提供的自动DOM差异和更新(例如,控制div元素的可见性)

从我对Blazor有限的理解来看,Blazor通常会在WebAssembly方法的返回数据中返回更新DOM所需的任何状态数据。 但是,如果从JavaScript使用invokeMethod或invokeMethodAsync,您必须自己管理返回和使用这些数据,但这可能会有问题,因为您的更新可能与Blazor的DOM状态视图冲突

因此,我提出了一种在Razor视图中生成隐藏按钮的黑客方法,例如:

<button id="arrow-left-button" @onclick="HandleArrowLeftPress"></button>
我知道这看起来真的很糟糕,但我所做的就是用箭头键移动屏幕上绝对定位的元素


如果有人知道更干净的方法(比如如何在处理程序回调中从JavaScript端强制更新Razor视图的名称),请让我知道。

这里有一个例子:您看到了多少延迟?当我在JS和接收它的C#方法中记录keypress时,我看不到超过1-2毫秒的差异。这是记录语句的差异-没有它们可能会少一些。谢谢,但这是一个对输入标记的操作绑定,正如我在问题中所写的但是,这有很多问题。我试图找到一种方法来绑定文档键控事件或任何其他没有这些限制的方法。有用的答案。我以前没有意识到,不序列化就不可能将原始事件传递给Blazor。
<button id="arrow-left-button" @onclick="HandleArrowLeftPress"></button>
document.getElementById('arrow-left-button').click();