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

时间:2021-05-25

最近给卫生局做一个表格上传/可视化系统,算是小有成果。今天把项目中的文件拖拽上传模块分离出来,做了一个独立的小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'号,放在模态框右上角表示退出按钮

截图:

整体界面

点击‘拖拽上传'按钮

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

上传成功,弹出提示

代码:

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,创建一个接收文件的对象,因为可以多次拖拽,这里采用单例模式创建对象Dragfilesvar 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='';}

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

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章