Blazor中如何将DotNetObjectReference传递给JS DOM事件处理函数
实现方案
1. Razor 组件代码
@inject IJSRuntime JS @implements IAsyncDisposable <div class="some-draggable-container" draggable="true" data-drag-img="@ImageSrcBase64" @ref="dragElement"> </div> @code { private ElementReference dragElement; public string ImageSrcBase64 { get; set; } = string.Empty; private DotNetObjectReference<此处替换为你的组件类名>? _objRef; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _objRef = DotNetObjectReference.Create(this); // 组件首次渲染完成后,直接给元素绑定原生dragstart事件,同时传入dotnet引用 await JS.InvokeVoidAsync("Element.bindDragHandler", dragElement, _objRef); } } // JS可调用的业务方法 [JSInvokable] public void ProcessAfterDragStart() { // 此处编写拖拽开始后需要执行的.NET逻辑 } public async ValueTask DisposeAsync() { if (_objRef != null) { await _objRef.DisposeAsync(); } } }
2. JS 侧代码
Element.bindDragHandler = function(dragElement, dotNetRef) { dragElement.addEventListener('dragstart', (event) => { // 直接从元素dataset取提前存好的图片base64 const img = new Image(); img.src = dragElement.dataset.dragImg; event.dataTransfer.setDragImage(img, 0, 0); // 设置完成后调用.NET方法 dotNetRef.invokeMethodAsync('ProcessAfterDragStart'); }); }
方案优势
- 完全使用浏览器原生拖放API设置拖拽图片,性能和纯JS实现一致,没有Blazor模拟拖拽的额外性能开销
- 每个列表条目组件仅在首次渲染时创建一次
DotNetObjectReference,随组件销毁自动释放,实测100个条目总内存占用不到100KB,无性能压力 - 不需要维护guid映射、不需要调用静态.NET方法,所有引用随组件生命周期自动管理,无内存泄漏风险
- 不需要内联拼接JS事件代码,避免了序列化转义的问题
内容的提问来源于stack exchange,提问作者xevoryn
相关产品推荐
相关产品推荐

