多文件的拖拽上传

在项目中碰到的多文件的拖拽上传总结。

html代码部分:
<
body> <div class="fileBox"> <p class="fileInputP vm"> <i>选择文件</i> <!-- 选中单个文件上传 --> <input type="file" multiple id="fileInput" /> </p> <span id="fileSpan" class="vm">或者将文件拖到此处</span> <div class="mask"></div> </div> <!-- 文件信息列表 --> <table width="50%" border="1" class="fileList_parent"> <thead> <tr> <th>书名</th> <th>类型</th> <th>大小</th> <th>进度</th> <th>操作</th> </tr> </thead> <tbody class="fileList"> </tbody> </table> <input type="button" value="上传" id="fileBtn" /> </body>
.fileBox {
            margin: 50px;
        }
        .fileInputP {
            display: inline-block;
             200px;
            height: 30px;
            border-radius: 5px;
            overflow: hidden;
            position: relative;
        }
        .fileInputP i {
            display: inline-block;
             200px;
            height: 30px;
            color: #fff;
            background: #7d8f33;
            text-align: center;
            line-height: 30px;
        }
        #fileInput {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            opacity: 0;
        }

        #fileSpan {
            display: inline-block;
             300px;
            height: 150px;
            border: 2px dashed #ccc;
            text-align: center;
            line-height: 150px;
        }

        .fileList_parent {
            margin: 50px;
            display: none;
        }

        .fileList_parent th {
            background: #dadada;
            font-weight: bold;
        }

        .fileList_parent th,
        .fileList_parent td {
            padding: 5px;
        }

        .fileList tr:nth-of-type(2n) {
            background: #dadada;
        }

        .progressParent {
             200px;
            height: 20px;
            border-radius: 5px;
            background: #ccc;
            overflow: hidden;
            position: relative;
        }

        .progress {
             0%;
            height: 20px;
            background: #7d8f33;
        }

        .progressNum {
            display: inline-block;
             100%;
            height: 20px;
            text-align: center;
            line-height: 20px;
            color: #fff;
            position: absolute;
            left: 0;
            top: 0;
        }

        #fileBtn {
            margin-left: 50px;
            display: none;
        }

下面是关键的js代码部份

  1 $(function() {
  2             //元素
  3             var oFileBox = $(".fileBox"); //选择文件父级盒子
  4             var oFileInput = $("#fileInput"); //选择文件按钮
  5             var oFileSpan = $("#fileSpan"); //选择文件框
  6             var oFileList_parent = $(".fileList_parent"); //表格
  7             var oFileList = $(".fileList"); //表格tbody
  8             var oFileBtn = $("#fileBtn"); //上传按钮
  9 
 10             var flieList = []; //数据,为一个复合数组
 11             var sizeObj = []; //存放每个文件大小的数组,用来比较去重
 12 
 13             //拖拽外部文件,进入目标元素触发
 14             oFileSpan.on("dragenter", function() {
 15                 $(this).text("可以释放鼠标了!").css("background", "#ccc");
 16             });
 17 
 18             //拖拽外部文件,进入目标、离开目标之间,连续触发
 19             oFileSpan.on("dragover", function() {
 20                 return false;
 21             });
 22 
 23             //拖拽外部文件,离开目标元素触发
 24             oFileSpan.on("dragleave", function() {
 25                 $(this).text("或者将文件拖到此处").css("background", "none");
 26             });
 27 
 28             //拖拽外部文件,在目标元素上释放鼠标触发
 29             oFileSpan.on("drop", function(ev) {
 30                 var fs = ev.originalEvent.dataTransfer.files;
 31                 analysisList(fs); //解析列表函数
 32                 $(this).text("或者将文件拖到此处").css("background", "none");
 33                 return false;
 34             });
 35 
 36             //点击选择文件按钮选文件
 37             oFileInput.on("change", function() {
 38                 analysisList(this.files);
 39             })
 40 
 41             //解析列表函数
 42             function analysisList(obj) {
 43                 //如果没有文件
 44                 if (obj.length < 1) {
 45                     return false;
 46                 }
 47 
 48                 for (var i = 0; i < obj.length; i++) {
 49 
 50                     var fileObj = obj[i]; //单个文件
 51                     var name = fileObj.name; //文件名
 52                     var size = fileObj.size; //文件大小
 53                     var type = fileType(name); //文件类型,获取的是文件的后缀
 54 
 55                     //文件大于30M,就不上传
 56                     if (size > 1024 * 1024 * 1024 || size == 0) {
 57                         alert('“' + name + '”超过了30M,不能上传');
 58                         continue;
 59                     }
 60 
 61                     //文件类型不为这三种,就不上传
 62                     /*if( ("pdf/txt/epub").indexOf(type) == -1 ){
 63                         alert('“'+ name +'”文件类型不对,不能上传');
 64                         continue;
 65                     }*/
 66 
 67                     //把文件大小放到一个数组中,然后再去比较,如果有比较上的,就认为重复了,不能上传
 68                     if (sizeObj.indexOf(size) != -1) {
 69                         alert('“' + name + '”已经选择,不能重复上传');
 70                         continue;
 71                     }
 72 
 73                     //给json对象添加内容,得到选择的文件的数据
 74                     var itemArr = [fileObj, name, size, type]; //文件,文件名,文件大小,文件类型
 75                     flieList.push(itemArr);
 76 
 77                     //把这个文件的大小放进数组中
 78                     sizeObj.push(size);
 79                 }
 80                 createList() //生成列表
 81                 oFileList_parent.show(); //表格显示
 82                 oFileBtn.show(); //上传按钮显示
 83             };
 84 
 85 
 86             //生成列表
 87             function createList() {
 88                 oFileList.empty(); //先清空元素内容
 89                 for (var i = 0; i < flieList.length; i++) {
 90 
 91                     var fileData = flieList[i]; //flieList数组中的某一个
 92                     var objData = fileData[0]; //文件
 93                     var name = fileData[1]; //文件名
 94                     var size = fileData[2]; //文件大小
 95                     var type = fileData[3]; //文件类型
 96                     var volume = bytesToSize(size); //文件大小格式化
 97 
 98 
 99                     var oTr = $("<tr></tr>");
100                     var str = '<td><cite title="' + name + '">' + name + '</cite></td>';
101                     str += '<td>' + type + '</td>';
102                     str += '<td>' + volume + '</td>';
103                     str += '<td>';
104                     str += '<div class="progressParent">';
105                     str += '<p class="progress"></p>';
106                     str += '<span class="progressNum">0%</span>';
107                     str += '</div>';
108                     str += '</td>';
109                     str += '<td><a href="javascript:;" class="operation">删除</a></td>';
110 
111                     oTr.html(str);
112                     oTr.appendTo(oFileList);
113                 }
114             }
115 
116             //删除表格行
117             oFileList.on("click", "a.operation", function() {
118                 var oTr = $(this).parents("tr");
119                 var index = oTr.index();
120                 oTr.remove(); //删除这一行
121                 flieList.splice(index, 1); //删除数据
122                 sizeObj.splice(index, 1); //删除文件大小数组中的项
123 
124                 //console.log(flieList);
125                 //console.log(sizeObj);
126 
127             });
128 
129 
130             //上传
131             oFileBtn.on("click", function() {
132                 oFileBtn.off();
133                 var tr = oFileList.find("tr"); //获取所有tr列表
134                 var successNum = 0; //已上传成功的数目
135                 oFileList.off(); //取消删除事件
136                 oFileBox.slideUp(); //隐藏输入框
137                 oFileList.find("a.operation").text("等待上传");
138 
139 
140                 for (var i = 0; i < tr.length; i++) {
141                     uploadFn(tr.eq(i), i); //参数为当前项,下标
142                 }
143 
144                 function uploadFn(obj, i) {
145 
146                     var formData = new FormData();
147                     var arrNow = flieList[i]; //获取数据数组的当前项
148 
149                     // 从当前项中获取上传文件,放到 formData对象里面,formData参数以key name的方式
150                     var result = arrNow[0]; //数据
151                     formData.append("imageFile", result); // 给后台传的参数
152 
153                     var name = arrNow[1]; //文件名
154                     formData.append("email", name); // 给后台传的参数
155 
156                     var progress = obj.find(".progress"); //上传进度背景元素
157                     var progressNum = obj.find(".progressNum"); //上传进度元素文字
158                     var oOperation = obj.find("a.operation"); //按钮
159 
160                     oOperation.text("正在上传"); //改变操作按钮
161                     oOperation.off();
162 
163                     var request = $.ajax({
164                         type: "POST",
165                         url: "// 上传文件的路径",
166                         data: formData, //这里上传的数据使用了formData 对象
167                         processData: false, //必须false才会自动加上正确的Content-Type
168                         contentType: false,
169 
170                         //这里我们先拿到jQuery产生的XMLHttpRequest对象,为其增加 progress 事件绑定,然后再返回交给ajax使用
171                         xhr: function() {
172                             var xhr = $.ajaxSettings.xhr();
173                             if (onprogress && xhr.upload) {
174                                 xhr.upload.addEventListener("progress", onprogress, false); 
175                                 return xhr;
176                             }
177                         },
178 
179                         //上传成功后回调
180                         success: function() {
181                             oOperation.text("成功");
182                             successNum++;
183                             console.log(successNum);
184                             if (successNum == tr.length) {
185                                 open("http://www.baidu.com", "_self"); //如果全部传成功了,跳转
186                             }
187                         },
188 
189                         //上传失败后回调
190                         error: function() {
191                             oOperation.text("重传");
192                             oOperation.on("click", function() {
193                                 request.abort(); //终止本次
194                                 uploadFn(obj, i);
195                             });
196                         }
197 
198                     });
199 
200 
201                     //侦查附件上传情况 ,这个方法大概0.05-0.1秒执行一次
202                     function onprogress(evt) {
203                         var loaded = evt.loaded; //已经上传大小情况
204                         var tot = evt.total; //附件总大小
205                         var per = Math.floor(100 * loaded / tot); //已经上传的百分比
206                         progressNum.html(per + "%");
207                         progress.css("width", per + "%");
208                     }
209                 }
210             });
211         })
212 
213         //字节大小转换,参数为b
214         function bytesToSize(bytes) {
215             var sizes = ['Bytes', 'KB', 'MB'];
216             if (bytes == 0) return 'n/a';
217             var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
218             return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
219         };
220 
221         //通过文件名,返回文件的后缀名
222         function fileType(name) {
223             var nameArr = name.split(".");
224             return nameArr[nameArr.length - 1].toLowerCase();
225         }
View Code

 完成后效果如下图所示:

原文地址:https://www.cnblogs.com/Sabo-dudu/p/7089604.html