Blazor中如何在Razor方法内调用window.addEventListener绑定C#方法
Blazor Razor 中绑定window鼠标事件的实现方案
Blazor 运行环境无法直接在C#代码中访问浏览器window对象,所有DOM、BOM操作都需要通过 JS互操作(IJSRuntime) 实现,你需要通过JS注册事件监听,再回调触发C#方法。
- 步骤1:在Razor组件中注入IJSRuntime服务
如果是.razor文件顶部直接声明:
@inject IJSRuntime JSRuntime @implements IAsyncDisposable
如果是代码后置类:
[Inject] protected IJSRuntime JSRuntime { get; set; }
- 步骤2:声明可被JS调用的C#方法,并创建DotNet引用
// 存储DotNet实例引用,用于JS回调C#方法,尖括号内替换为你当前组件的类名 private DotNetObjectReference<YourComponentName>? _dotNetRef; protected override void OnInitialized() { _dotNetRef = DotNetObjectReference.Create(this); } // 标注JSInvokable允许JS调用该方法 [JSInvokable] public void OnMouseMove(int clientX, int clientY) { // 这里写你的OnMouseMove逻辑,按需传入需要的事件参数即可 } [JSInvokable] public void OnMouseUp() { // 这里写你的OnMouseUp逻辑 // 触发mouseup后移除事件监听,避免重复绑定 _ = JSRuntime.InvokeVoidAsync("removeMouseListeners"); }
- 步骤3:编写注册/移除事件监听的JS代码
把以下JS代码放到你的项目公共脚本文件(比如wwwroot/js/common.js),或Blazor入口页面(_Host.cshtml/App.razor)的<script>标签中:
// 存储事件处理函数,用于后续移除监听 let mouseMoveHandler = null; let mouseUpHandler = null; window.addMouseListeners = (dotNetRef) => { // 先移除之前的监听避免重复绑定 removeMouseListeners(); mouseMoveHandler = (e) => { // 回调C#的OnMouseMove方法,按需传递事件参数 dotNetRef.invokeMethodAsync('OnMouseMove', e.clientX, e.clientY); }; mouseUpHandler = () => { dotNetRef.invokeMethodAsync('OnMouseUp'); }; window.addEventListener('mousemove', mouseMoveHandler); window.addEventListener('mouseup', mouseUpHandler); } window.removeMouseListeners = () => { if(mouseMoveHandler) { window.removeEventListener('mousemove', mouseMoveHandler); mouseMoveHandler = null; } if(mouseUpHandler) { window.removeEventListener('mouseup', mouseUpHandler); mouseUpHandler = null; } }
- 步骤4:修改你的OnMouseDown方法,调用JS注册监听
private async void OnMouseDown(MouseEventArgs e) { if (!Disabled && !Readonly && _dotNetRef != null) { await JSRuntime.InvokeVoidAsync("addMouseListeners", _dotNetRef); } }
- 步骤5:资源释放,避免内存泄漏
实现异步释放方法,组件销毁时清理引用和事件监听:
public async ValueTask DisposeAsync() { if (_dotNetRef != null) { await JSRuntime.InvokeVoidAsync("removeMouseListeners"); _dotNetRef.Dispose(); _dotNetRef = null; } }
- 注意
[JSInvokable]标注的方法访问级别必须是public,JS才能正常调用 - 按需传递事件参数即可,不需要把整个MouseEvent对象传到C#,避免性能损耗
- 所有异步JS调用建议加上异常捕获,处理JS执行失败的场景
内容的提问来源于stack exchange,提问作者Melih Altıntaş
相关产品推荐
相关产品推荐

