当前位置 : 主页 > 编程语言 > 其它开发 >

Blazor 使用拖放(drag and drop)上传文件 , 粘贴文件上传

来源:互联网 收集:自由互联 发布时间:2022-05-15
在很多上传文件的应用实例中, 都可以看到[拖放文件到此上传]这种骚功能 ,今天我们就来试试Blazor能不能完成这个想法. 原文链接:https://www.cnblogs.com/densen2014/p/16128246.html 简述HTML5拖放
在很多上传文件的应用实例中, 都可以看到[拖放文件到此上传]这种骚功能 ,今天我们就来试试Blazor能不能完成这个想法.

原文链接:https://www.cnblogs.com/densen2014/p/16128246.html

简述HTML5拖放

拖放是HTML5标准的一部分,任何元素都能够拖放,也能够将本地的文件拖放到页面上。

设置元素可拖放

为了使元素可拖动,把 draggable 属性设置为 true

<img draggable="true" />
拖放事件

有7个拖放事件可以捕获,如下:

dragstart:开始拖元素触发

dragenter:元素拖进可drop元素(绑定drop事件的元素)时触发

dragover:当元素拖动到drop元素上时触发

drop:当元素放下到drop元素触发

dragleave :当元素离开drop元素时触发

drag:每次元素被拖动时会触发

dragend:放开拖动元素时触发

完成一次拖放的事件过程是: dragstart –> dragenter –> dragover –> drop –> dragend

浏览器支持

Edge、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。

拖拽上传实现 1.新建工程n02drag,将项目添加到解决方案中
dotnet new blazorserver -o n02drag
dotnet sln add n02drag/n02drag.csproj
2.在文件夹wwwroot/lib,添加drag子文件夹,新建app.js文件

先阻止页面默认的拖放行为,不然页面会被拖放的文件替换了。

//阻止浏览器默认行为
document.addEventListener( "dragleave", function(e) {
     e.preventDefault();
}, false);
document.addEventListener( "drop", function(e) {
     e.preventDefault();
}, false);
document.addEventListener( "dragenter", function(e) {
     e.preventDefault();
}, false);
document.addEventListener( "dragover", function(e) {
     e.preventDefault();
}, false);

设置drop区域

当文件拖放到drop区域时,就能触发上传。

    element.addEventListener("drop", function (e) {

        try {
            var fileList = e.dataTransfer.files; //获取文件对象
            //检测是否是拖拽文件到页面的操作
            if (fileList.length == 0) {
                return false;
            }

            inputFile.files = e.dataTransfer.files;
            const event = new Event('change', { bubbles: true });
            inputFile.dispatchEvent(event);
        }
        catch (e) {
            wrapper.invokeMethodAsync('DropAlert', e);
        }
    }, false);
2.在文件Pages/Index.razor,添加上传组件

页面

@implements IAsyncDisposable
@inject IJSRuntime JS

<div @ref="UploadElement" style="padding: 20px; width: 200px; height: 200px; background-color: cornflowerblue; border: 2px dashed #0087F7; border-radius: 5px; ">
    <p>拖放上传文件</p>
     <InputFile OnChange="OnChange" class="form-control" multiple @ref="inputFile"/>
</div>

<pre>
<code>
        @uploadstatus
</code>
</pre>

代码

  1. InputFile 开启 multiple ,接受多文件上传
  2. 使用JS隔离技术
  3. Dispose处理回收

@code{
    [Inject] protected Microsoft.AspNetCore.Hosting.IWebHostEnvironment? HostEnvironment { get; set; } //获取IWebHostEnvironment

    protected ElementReference UploadElement { get; set; }
    protected InputFile? inputFile { get; set; }

    private DotNetObjectReference<Index>? wrapper;

    private IJSObjectReference? module;
    private IJSObjectReference? dropInstance;

    protected string UploadPath = "";
    protected string? uploadstatus;
    long maxFileSize = 1024 * 1024 * 15;

    protected override void OnAfterRender(bool firstRender)
    {
        if (!firstRender) return;
        UploadPath = Path.Combine(HostEnvironment!.WebRootPath, "Upload"); //初始化上传路径
        if (!Directory.Exists(UploadPath)) Directory.CreateDirectory(UploadPath); //不存在则新建目录
    }

    protected async Task OnChange(InputFileChangeEventArgs e)
    {
        int i = 0;
        var selectedFiles = e.GetMultipleFiles(100);
        foreach (var item in selectedFiles)
        {
            i++;
            await OnSubmit(item);
            uploadstatus += Environment.NewLine + $"[{i}]: " + item.Name;
        }
    }

    protected async Task OnSubmit(IBrowserFile efile)
    {
        if (efile == null) return;
        var tempfilename = Path.Combine(UploadPath, efile.Name);
        await using FileStream fs = new(tempfilename, FileMode.Create);
        using var stream = efile.OpenReadStream(maxFileSize);
        await stream.CopyToAsync(fs);
        StateHasChanged();
    }


    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender) return;

        module = await JS.InvokeAsync<IJSObjectReference>("import", "./lib/drag/app.js");
        wrapper = DotNetObjectReference.Create(this);
        dropInstance = await module.InvokeAsync<IJSObjectReference>("init", wrapper , UploadElement, inputFile!.Element);
    }

    [JSInvokable]
    public void DropAlert(string msg)
    {
        uploadstatus  += Environment.NewLine + $"[!Alert!]: " + msg;
        StateHasChanged();
    }


    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (dropInstance != null)
        {
            await dropInstance.InvokeVoidAsync("dispose");
            await dropInstance.DisposeAsync();
        }

        if (wrapper != null)
        {
            wrapper.Dispose();
        }

        if (module != null)
        {
            await module.DisposeAsync();
        }
    }

}
3.就这么简单吗?我们还可以加上一些骚功能
网友评论