Blazor实现PDF/PNG/JPG文件拖拽上传并打印文件名求助
Blazor实现文件拖拽/选择功能的正确姿势
先改Razor模板
把原来的硬编码ID换成Blazor的组件引用和内置事件,避免直接操作DOM踩坑:
<div @ref="dropZoneRef" class="bg-white flex flex-col items-center justify-center py-20 border border-slate-200 rounded-md relative" @ondragenter="HandleDragEnter" @ondragover="HandleDragOver" @ondragleave="HandleDragLeave" @ondrop="HandleDrop"> <img src="\assets\AIDocReader\icons\file-upload-input.svg" alt="Icon for upload file" class="w-8"> <p>Drag & drop or <span class="text-tertiary">browse</span> your files</p> <input type="file" accept=".pdf, .png, .jpg" class="absolute top-0 left-0 h-full w-full cursor-pointer opacity-0" @onchange="HandleFileSelect" /> <p>@selectedFileName</p> </div>
写C#逻辑
在组件的@code块里处理所有事件,用Blazor自带的API,少写原生JS:
@inject IJSRuntime JSRuntime <!-- 上面的模板代码 --> @code { // 引用拖拽区域的DOM元素 private ElementReference dropZoneRef; // 用来显示选中的文件名 private string selectedFileName = string.Empty; // 处理点击选择文件的情况 private void HandleFileSelect(ChangeEventArgs e) { var files = e.Value as IReadOnlyList<IBrowserFile>; if (files?.Count > 0) { selectedFileName = files[0].Name; Console.WriteLine($"选中的文件:{selectedFileName}"); } } // 拖拽进入区域时,添加高亮样式 private void HandleDragEnter(DragEventArgs e) { e.PreventDefault(); // 通过JS互操作给元素加类 _ = JSRuntime.InvokeVoidAsync("addClass", dropZoneRef, "bg-background"); } // 拖拽悬浮时,必须阻止默认行为,否则浏览器会打开文件 private void HandleDragOver(DragEventArgs e) { e.PreventDefault(); } // 拖拽离开区域,移除高亮样式 private void HandleDragLeave(DragEventArgs e) { e.PreventDefault(); _ = JSRuntime.InvokeVoidAsync("removeClass", dropZoneRef, "bg-background"); } // 拖拽放下时处理文件 private async Task HandleDrop(DragEventArgs e) { e.PreventDefault(); _ = JSRuntime.InvokeVoidAsync("removeClass", dropZoneRef, "bg-background"); // 通过JS获取拖拽的文件列表 var files = await JSRuntime.InvokeAsync<IReadOnlyList<IBrowserFile>>( "getDroppedFiles", e.DataTransfer); if (files?.Count > 0) { selectedFileName = files[0].Name; Console.WriteLine($"拖拽的文件:{selectedFileName}"); } } }
加少量辅助JS
在wwwroot下新建file-helpers.js,写几个简单的工具函数:
// 给元素添加CSS类 window.addClass = function(element, className) { element.classList.add(className); } // 移除元素的CSS类 window.removeClass = function(element, className) { element.classList.remove(className); } // 提取拖拽的文件信息 window.getDroppedFiles = function(dataTransfer) { return Array.from(dataTransfer.files).map(file => ({ Name: file.name, Size: file.size, ContentType: file.type })); }
然后在入口文件里引入这个JS:
- Server项目:
_Host.cshtml里加<script src="file-helpers.js"></script> - WebAssembly项目:
index.html里加同样的代码
你之前的问题出在哪?
- JS代码执行时机不对:Blazor组件还没渲染好,你的JS就去
getElementById,自然找不到元素 - 直接操作DOM和Blazor冲突:Blazor会管理DOM渲染,你用JS改的内容可能被组件重新渲染覆盖
@onchange调用JS的方式不符合Blazor的交互逻辑,应该用C#事件或者规范的JS互操作
内容的提问来源于stack exchange,提问作者Anna Bondarets
相关产品推荐
相关产品推荐

