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

来源:互联网 发布:mac电磁阀说明书 编辑:程序博客网 时间:2024/06/07 16:53

最近碰到一个需求。需要上传很多图片,但是又不是批量上传。场景是这样的。我需要从数据表中查出一行一行的数据,每一行都需要更新一个对应的图片。天才需求方不喜欢批量上传,因为需要让他们给每个图片命名。
原生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 0
原创粉丝点击