前端页面文件拖拽上传模块js代码示例

最近给卫生局做一个表格上传/可视化系统,算是小有成果。今天把项目中的文件拖拽上传模块分离出来,做了一个独立的小demo,并把相关代码打包上传到了我的github中,为了其他学习者和开发者提供拙见。

gitHub地址:

由于代码中我的注释很详尽,所以具体逻辑实现及不介绍了,大家直接看代码及能明白。现在简单列一个功能清单和一些用到的知识点清单:

  • 模态框
  • 文件的批量上传
  • 使用formData API 封装数据 并通过ajax方法提交
  • 读取拖放文件,ondrop事件 dataTransfer对象
  • 清空所有文件

知识点:

  • 单例模式:构建一个单例模式的formData容器
  • 事件冒泡,事件委托:动态添加删除单个文件的方法
  • css各种布局,BFC
  • CSS 伪类 link vistied hover active
  • html 离线操作文档:创建fragment 离线操作,提高性能,减少浏览器的重绘和回流
  • 原型链,原型方法:为formData对象添加一个删除所有文件的方法
  • CSS伪对象,结合after伪对象画一个‘X'号,放在模态框右上角表示退出按钮

截图:

整体界面

点击‘拖拽上传'按钮

拖拽文件到虚线框,文件拖入会边框变红提示

上传成功,弹出提示

代码:

1. html:

Title
拖拽上传演示模板。点击下方按钮,弹出模态框

CSS

rush:css;"> .overlay{ z-index: 99; position:fixed; display: none; top:0; left:0; width: 100%; height: 100%; background-color: #333; opacity:0.5; } .dropBox{ z-index: 100; display: none; position: fixed; width:500px; height:520px; margin:auto; top:0; right:0; bottom: 0; left:0; background-color: #fff; border-radius:6px; transition-duration: 0.9s; -webkit-transition-duration: 0.9s; overflow:hidden; text-align: center; } .items-container{ padding: 10px; } .content{ border: 3px dashed gray; border-radius: 10px; margin: 10px 20px; height:400px; overflow: auto; padding:2px 8px; }

.head{
margin:0px;
font-size:30px;
color:#aaa;
}
.footer{
margin:5px auto
}
.btn{
border-radius: 20px;
Box-sizing: border-Box;
border-width: 2px;
background-color: transparent;
font-size: 14px;
font-weight: 500;
padding: 7px 18px
}
/一个叉号,表示推出界面/
.css-close{display:inline-block; width:15px; height:2px; background:#000; font-size:0; line-height:0;vertical-align:middle;-webkit-transform: rotate(45deg);}
.css-close:after { content:'.'; display:block; width:15px; height:2px; background:#000;-webkit-transform: rotate(90deg);}

/表格样式/
.table{
width:100%;
border-collapse: collapse;
}

content tr:first-child td{

border-top-width: 0px;
}

content tr td:last-child{

cursor: pointer;
color: red;
}

content tr td{

padding: 8px;
white-space: Nowrap;
overflow: hidden;
text-overflow:ellipsis;
border-top:1px solid #9A9A9A;
}

content tr:hover{

background-color: #d5d5d5;
}

content tr:active{

background-color: #9A9A9A;
}
a:link{
color:blue;
}
a:visited{
color:blue;
}
a:hover{
color:blue;
}
a:active{
color:red;
}

js代码

rush:js;"> function showModal() { //打开上传框 var modal = document.getElementById('modal'); var overlay = document.getElementsByClassName('overlay')[0]; overlay.style.display = 'block'; modal.style.display = 'block'; } function closeModal() { //关闭上传框 var modal = document.getElementById('modal'); var overlay = document.getElementsByClassName('overlay')[0]; overlay.style.display = 'none'; modal.style.display = 'none'; } //用DOM2级方法为右上角的叉号和黑色遮罩层添加事件:点击后关闭上传框 document.getElementsByClassName('overlay')[0].addEventListener('click',closeModal,false); document.getElementById('close').addEventListener('click',false);

//利用html5 FormData() API,创建一个接收文件的对象,因为可以多次拖拽,这里采用单例模式创建对象Dragfiles
var Dragfiles=(function (){
var instance;
return function(){
if(!instance){
instance = new FormData();
}
return instance;
}
}());
//为Dragfiles添加一个清空所有文件方法
FormData.prototype.deleteall=function () {
var _this=this;
this.forEach(function(value,key){
_this.delete(key);
})
}

//添加拖拽事件
var dz = document.getElementById('content');
dz.ondragover = function (ev) {
//阻止浏览器认打开文件的操作
ev.preventDefault();
//拖入文件后边框颜色变红
this.style.borderColor = 'red';
}

dz.ondragleave = function () {
//恢复边框颜色
this.style.borderColor = 'gray';
}
dz.ondrop = function (ev) {
//恢复边框颜色
this.style.borderColor = 'gray';
//阻止浏览器认打开文件的操作
ev.preventDefault();
var files = ev.dataTransfer.files;
var len=files.length,i=0;
var frag=document.createDocumentFragment(); //为了减少js修改dom树的频度,先创建一个fragment,然后在fragment里操作
var tr,time,size;
var newForm=Dragfiles(); //获取单例
var it=newForm.entries(); //创建一个迭代器,测试用
while(i<len){
tr=document.createElement('tr');
//获取文件大小
size=Math.round(files[i].size * 100 / 1024) / 100 + 'KB';
//获取格式化的修改时间
time = files[i].lastModifiedDate.toLocaleDateString() + ' '+files[i].lastModifiedDate.toTimeString().split(' ')[0];
tr.innerHTML='<td>'+files[i].name+'</td><td>'+time+'</td><td>'+size+'</td><td>删除</td>';
console.log(size+' '+time);
frag.appendChild(tr);
//添加文件到newForm
newForm.append(files[i].name,files[i]);
//console.log(it.next());
i++;
}
this.childNodes[1].childNodes[1].appendChild(frag);
//为什么是‘1'?文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释成节点。而且都包含在childNodes属性所返回的数组中.不同于jade模板
}
function blink()
{
document.getElementById('content').style.borderColor = 'gray';
}

//ajax上传文件
function upload(){
if(document.getElementsByTagName('tbody')[0].hasChildNodes()==false){
document.getElementById('content').style.borderColor = 'red';
setTimeout(blink,200);
return false;
}
var data=Dragfiles(); //获取formData
$.ajax({
url: 'upload',type: 'POST',data: data,async: true,cache: false,contentType: false,processData: false,success: function (data) {
alert('succeed!') //可以替换为自己的方法
closeModal();
data.deleteall(); //清空formData
$('.tbody').empty(); //清空列表
},error: function (returndata) {
alert('Failed!') //可以替换为自己的方法
}
});
}
// 用事件委托的方法为‘删除'添加点击事件,使用jquery中的on方法
$(".tbody").on('click','tr td:last-child',function(){
//删除拖拽框已有的文件
var temp=Dragfiles();
var key=$(this).prev().prev().prev().text();
console.log(key);
temp.delete(key);
$(this).parent().remove();
});
//清空所有内容
function clearall(){
if(document.getElementsByTagName('tbody')[0].hasChildNodes()==false){
document.getElementById('content').style.borderColor = 'red';
setTimeout(blink,300);
return false;
}
var data=Dragfiles();
data.deleteall(); //清空formData
//$('.tbody').empty(); 等同于以下方法
document.getElementsByTagName('tbody')[0].innerHTML='';
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...