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

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

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

模态框

文件的批量上传

使用formData API 封装数据 并通过ajax方法提交

读取拖放文件,ondrop事件 dataTransfer对象

清空所有文件

知识点:

单例模式:构建一个单例模式的formData容器

事件冒泡,事件委托:动态添加删除单个文件的方法

css各种布局,BFC

CSS 伪类 link vistied hover active

html 离线操作文档:创建fragment 离线操作,提高性能,减少浏览器的重绘和回流

原型链,原型方法:为formData对象添加一个删除所有文件的方法

CSS伪对象,结合after伪对象画一个‘X'号,放在模态框右上角表示退出按钮

截图:

整体界面

90d1f5e052f0577686e76304707508e0.png

点击‘拖拽上传'按钮

b799ef727cc0d837fd2c70a594d37ca2.png

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

0c467178dfd77291a628d15a33c51d88.png

上传成功,弹出提示

563896d4ca6ca5cc46b4cca9872d5065.png

代码:

1. html:

Title

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

点击上传

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

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='

'+files[i].name+''+time+''+size+'删除';

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='';

}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值