欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-12 23:08:17
最近给卫生局做一个表格上传/可视化系统,算是小有成果。今天把项目中的文件拖拽上传模块分离出来,做了一个独立的小demo,并把相关代码打包上传到了我的github中,为了其他...

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

github地址:https://github.com/codeplay2015/dragtoupload

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

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

知识点:

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

截图:

整体界面

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

点击‘拖拽上传'按钮

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

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

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

上传成功,弹出提示

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

代码:

1. html:

<!doctype html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <title>title</title>
 <link rel="stylesheet" href="demo.css" rel="external nofollow" >
</head>
<body>
 <!--遮罩-->
 <div class="overlay"></div>
 <!--模态框-->
 <div id="modal" class="dropbox">
  <div class="items-container">
   <div id="close" style="cursor:pointer;float: right;width:20px">
    <span class="css-close"></span>
   </div>
   <div>
    <p class="head"><b>拖拽文件至此</b></p>
    <div class="content" id="content">
     <table class="table">
      <tbody class="tbody"></tbody>
     </table>
    </div>
    <div class="footer">
     <button class="btn" onclick="upload()">开始上传</button>
    </div>
    <a href='#' onclick='clearall()' style='position:absolute;bottom:10px;right:30px;'>清空所有</a>
   </div>
  </div>
 </div>
 <!--页面内容-->
 <div style="margin-top:40vh;text-align: center;">
  <p>拖拽上传演示模板。点击下方按钮,弹出模态框</p>
  <button class="btn" onclick="showmodal()">点击上传</button>
 </div>
 <!--嵌入脚本-->
 <script src="jquery-1.10.2.js" type="text/javascript"></script>
 <script src="demo.js" type="text/javascript"></script>
</body>
</html>

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代码:

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', closemodal, 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='';
}

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