我尝试在Blazor上编写一个简单的蛇游戏,但找不到任何将事件绑定到文档上的方法。
有机会将事件绑定到不同的元素上,例如 div 或 input 。
例如:<input onkeypress="@KeyPressInDiv"/>
public void KeyPressInDiv(UIKeyboardEventArgs ev)
{....}
我想,对于javascript方法document.onkeydown = function (evt) {}
应该有一个类比
我发现了解决此问题的几种方法:
1)使用JS进行绑定并调用blazor代码(摘自https://github.com/aesalazar/AsteroidsWasm)
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)可以在上面添加输入标签并绑定事件。
这确实比以前更快,但是:
-它主要看起来像个杂种,然后是解决方案
-我们无法捕获许多动作,例如Up / DownArrow
是否有直接方法绑定blazor的文档事件?
更新1:我创建了一个简单的项目,以更好地解释我尝试达到的目标。 https://github.com/XelMed/BlazorSnake
Snake有3种实现方式:
1)纯js-这是预期的行为
2)在blazor中使用js-使用JsInterop从JS代码调用blazor函数
3)使用输入标签-在输入标签上绑定事件以控制Snake
答案 0 :(得分:0)
您可以仅使用所需的事件标签(onkeyup / onmousemove ....)将事件直接绑定到C#方法。
@page "/"
<div>
<input type="text" onkeyup=@KeyUp />
</div>
@functions {
void KeyUp(UIKeyboardEventArgs e)
{
Console.WriteLine(e.Key);
}
protected override Task OnInitAsync()
{
return Task.CompletedTask;
}
}
答案 1 :(得分:0)
"Is there a direct way for binding on documents events from blazor?"
Nyet
在Blazor中,您可以执行以下操作:
<input type="button" onclick="window.alert('Hello world!')" />
也许这可以给您一些想法...
希望这对您有帮助...
答案 2 :(得分:0)
也许使用JsInterop向文档中添加一个事件侦听器,并为该事件分配一个匿名函数,该函数使用偶数参数调用C#方法。
例如您的JsInterop.js:
document.addEventListener('onkeypress', function (e) {
DotNet.invokeMethodAsync('Snake', 'OnKeyPress', serializeEvent(e))
});
将serializeEvent用作Follos以避免某些古怪:
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
}
答案 3 :(得分:0)
我和您有相同的要求,并且我设法使用invokeMethodAsync将文档事件(例如keydown)连接到我的Razor方法,但是后来我发现如果Blazor提供了自动DOM差异和更新功能,我就错过了Blazor提供的功能。 Razor方法更改绑定到HTML元素的某些状态(例如,控制div元素的可见性)。
(根据我对Blazor的有限了解),通常Blazor在WebAssembly方法的返回数据中返回更新DOM所需的任何状态数据。 但是,如果您使用JavaScript的invokeMethod或invokeMethodAsync,则必须自己管理返回和使用此数据,但这可能会有问题,因为您的更新可能与Blazor的DOM状态视图冲突。
因此,我想出了一种巧妙的方法,可以在Razor视图中生成隐藏的按钮,例如:
<button id="arrow-left-button" @onclick="HandleArrowLeftPress"></button>
然后在JavaScript方面,我连接了一个文档事件,该事件通过ID查找该按钮并对其调用.click():
document.getElementById('arrow-left-button').click();
我知道这看起来确实很糟糕,但是它确实适用于我所做的事情,即使用箭头键在屏幕上移动绝对定位的元素。
如果有人知道更简洁的方法(例如如何在处理程序回调中从JavaScript端通过名称强制更新Razor视图),请告诉我。