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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010582082/article/details/72479938

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

gitHub地址:https://github.com/codeplay2015/dragToUpload


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

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

知识点:

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

截图:
整体界面
整体界面
点击‘拖拽上传’按钮
点击‘拖拽上传’按钮
拖拽文件到虚线框,文件拖入会边框变红提示
这里写图片描述
上传成功,弹出提示
这里写图片描述

—————————-、
代码
1. html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="demo.css">
</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='';
}
展开阅读全文

没有更多推荐了,返回首页