简单封装一个上传插件——支持拖拽和预览

最近碰到一个需求。需要上传很多图片,但是又不是批量上传。场景是这样的。我需要从数据表中查出一行一行的数据,每一行都需要更新一个对应的图片。天才需求方不喜欢批量上传,因为需要让他们给每个图片命名。
原生input flie上传能满足对方需求,但是不能方便拖拽和预览图片。
作为一个二手前端,当然是到网上找各种插件。但是能在网上上架的插件都封装得太复杂,毕竟我使用的是很简单的功能,用不上那么牛逼的插件。无奈之下自己动手写了一个简单的。

html排版

核心思路:把input设为透明,放在一个div中。
具体实现:最外层套一个固定宽高的div,同时把div设为相对定位。内层写一个同样宽高,透明的上传input,设为绝对定位(这样能保证与外层div完全重合)。内层同一级再写一个div,用来存放文字,如“请将图片拖到此处”。

<div class='box' style='position:relative;width: 100px;height: 50px;border:1px solid #000'>
        <input type="file" class='browerfile' name="copy_pic[]"  style='position:absolute;width:100px;height:50px;float:left;opacity:0;z-index: 3'  id="datafile" />
        <div class='box_txt' style='position:absolute;z-index:1;width: 100%;height: 50;text-align:center;line-height: 50px;color:gray'>图片拖到此处</div>
</div>

页面打开效果。
这里写图片描述

其实这样就能实现文件的拖动上传了,但是整个功能的需求还需要一个预览的功能。

JS实现预览图片

其实,这里并没有直接把图片展示到页面,考虑到上传页面图片太大,都展示出来印象页面美观。所以,这里使用了一个bootstrap的弹出框popover,当点击的时候才弹出预览框。
核心思路:通过js获取页面上的图片地址,再将地址放到img标签中。
具体实现:使用change绑定到图片上传框上,当检测图片拖动过来时,调用获取图片地址方法。将获取到的图片放到外层div下,与上传input同级。(这里使用一个a标签,当点击的时候在弹出框中预览图片)。

 //获取图片路劲的方法,兼容多种浏览器,通过createObjectURL实现
function getObjectURL(file){
    var url = null;
    if(window.createObjectURL != undefined){
        url = window.createObjectURL(file);//basic
    }else if(window.URL != undefined){
        url = window.URL.createObjectURL(file);
    }else if(window.webkitURL != undefined){
        url = window.webkitURL.createObjectURL(file);
    }
    return url;
}


//实现上传样式
$(function(){
    $(".browerfile").change(function(){
        $(this).prev('.showpic').remove();
        var objUrl = getObjectURL(this.files[0]);
        if(objUrl){
            $(this).parent('.box').prepend('<a style="position:absolute;z-index:999;text-align:center;color:red" class="showpic" href="javascript:">已选择,预览</a>');
            var elem = $(this).prev('.showpic');
            elem.popover({
                trigger: 'mouseover', //触发方式
                placement:'bottom',
                html: true, // 为true的话,data-content里就能放html代码了
                content: "<img src="+objUrl+" style='width:240px;height:320'/>", //这里可以直接写字符串,也可以 是一个函数,该函数返回一个字符串;
            });
        }
    })

})

好了,到此我们的图片上传插件就完成了。简单好用。
这里写图片描述

但是在使用过程中发现一个问题。这里我深刻的体会到了“墨菲定律”。“如果事情有变坏的可能,不管这种可能性有多小,它总会发生。”
为了避免图片拖到上传框外面,导致文件被浏览器打开。我尽可能的把上传框调到很大,但是仍然会被反馈,文件被浏览器打开了。
所以,这篇文章才出现第三天。或者说这篇文章才出现,如果不是为了解决这个问题,我也不会写这篇文章。

优化功能

当然,为了使插件变得好用。需要发现问题后积极去解决。
如何去解决这个问题呢,其实也很简单。两行代码。
核心思路:当文件拖动到浏览器,并松开时。js能否拦截到,并阻止浏览器打开文件?
实现思路:下面两行代码中,第一行时当浏览器中有文件进入时,做出反应,不处理。第二行是当浏览器界面中,拖动文件的鼠标松手时,做出反应,这里同样,不处理。

document.ondragover=function(e){e.preventDefault();}
document.ondrop=function(e){e.preventDefault();}

当使用这两行代码到插件中时。很成功,图片不会被打开。但是也很失败,上传框中也不能接受拖动上传了。

这里我第一想法是,使用jquery类似的:not()选择器。但是作为一个二手前端,没有发现JavaScript有类似的功能(因为上面两个方法,jquery不支持),或许真没有。

找了半天后,我想到了一个办法,不知道ondrop这个方法实例化的e对象,是否能检测到当前操作的class或者id? 通过console.log打印之后还真发现能检测到。所以,我的代码改成了下面部分。

document.ondragover=function(e){e.preventDefault();};
document.ondrop=function(e){
    // console.log(e);
    if (e.target.className=='browerfile') {
        return ;
    }else{
        alert('大哥,请拖动到上传区域才能上传。')
        e.preventDefault();
    }

}

这里写图片描述

好了,终于成功完成任务。这个小插件也离完美更近了一步。

其实为什么写这篇文章,主要还是因为拖动文件、禁止浏览器打开文件、限制部分div不能拖动的相关文章还是比较少。毕竟h5都使用那么广了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我来简单介绍一下如何封装一个简单插件DEMO。 首先,我们需要创建一个新的UE5项目。在这个项目中,我们将创建一个简单插件,用于在游戏中显示一些文本。 1. 创建插件 在UE5编辑器中,选择File -> New C++ Class,选择Plugin Class,并为插件命名。 2. 添加代码 在插件源代码的Private目录下,创建一个名为MyPlugin.cpp的文件。在这个文件中,我们将编写插件功能。 ```cpp #include "MyPlugin.h" #include "Modules/ModuleManager.h" void FMyPluginModule::StartupModule() { UE_LOG(LogTemp, Warning, TEXT("MyPlugin has started!")); } void FMyPluginModule::ShutdownModule() { UE_LOG(LogTemp, Warning, TEXT("MyPlugin has shut down!")); } IMPLEMENT_MODULE(FMyPluginModule, MyPlugin) ``` 这个代码很简单,它仅仅是在插件启动和关闭时输出日志信息。 3. 编译插件 在UE5编辑器中,选择File -> Generate Visual Studio project files,然后在Visual Studio中打开项目。构建项目,以确保生成正确的插件二进制文件。 4. 将插件添加到项目中 在UE5编辑器中,选择Edit -> Plugins,然后选择Installed中的MyPlugin插件。在插件详情页中,启用插件并重新启动编辑器。 5. 使用插件 在游戏中,可以使用以下代码来使用插件: ```cpp #include "MyPlugin.h" void AMyActor::BeginPlay() { Super::BeginPlay(); if (FModuleManager::Get().IsModuleLoaded("MyPlugin")) { UE_LOG(LogTemp, Warning, TEXT("MyPlugin is loaded!")); } else { UE_LOG(LogTemp, Warning, TEXT("MyPlugin is not loaded!")); } } ``` 这个代码很简单,它只是检查插件是否已加载并输出日志信息。 这就是封装一个简单的UE5插件DEMO所需要的步骤。通过这个DEMO,你可以了解到如何创建和使用一个简单插件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值