附件组件多附件实现文件上传进度条(ajax上传方式)

分享 未结
11 2312
永远
永远 2018-5-14
悬赏:20飞吻
建议收录到代码中,不然每次升级折腾一下 [伤心]

1.修改 upload.js 关键 代码如下 "--------------ajax多附件上传进度条--------------" 看包裹的代码块
Class.prototype.upload = function(files, type){
var that = this
,options = that.config
,elemFile = that.elemFile[0]

//高级浏览器处理方式,支持跨域
,ajaxSend = function(){
var successful = 0, aborted = 0
,items = files || that.files || that.chooseFiles || elemFile.files
,allDone = function(){ //多文件全部上传完毕的回调
if(options.multiple && successful + aborted === that.fileLength){
typeof options.allDone === 'function' && options.allDone({
total: that.fileLength
,successful: successful
,aborted: aborted
});
}
};
//--------------ajax多附件上传进度条--------------
var xhrOnProgress=function(fun) {
xhrOnProgress.onprogress = fun; //绑定监听
//使用闭包实现监听绑
return function() {
//通过$.ajaxSettings.xhr();获得XMLHttpRequest对象
var xhr = $.ajaxSettings.xhr();
//判断监听函数是否为函数
if (typeof xhrOnProgress.onprogress !== 'function')
return xhr;
//如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去
if (xhrOnProgress.onprogress && xhr.upload) {
xhr.upload.onprogress = xhrOnProgress.onprogress;
}
return xhr;
}
}
//--------------ajax多附件上传进度条--------------
layui.each(items, function(index, file){
var formData = new FormData();

formData.append(options.field, file);

//追加额外的参数
layui.each(options.data, function(key, value){
value = typeof value === 'function' ? value() : value;
formData.append(key, value);
});

//提交文件
$.ajax({
url: options.url
,type: options.method
,data: formData
,contentType: false
,processData: false
,dataType: 'json'
,headers: options.headers || {}
,success: function(res){
successful++;
done(index, res);
allDone();
}
,error: function(){
aborted++;
that.msg('请求上传接口出现异常');
error(index);
allDone();
},
//--------------ajax多附件上传进度条--------------
xhr:xhrOnProgress(function(e){
//var percent=e.loaded / e.total;//计算百分比
//console.log(percent);
xhr(index,e);
})
//--------------ajax多附件上传进度条--------------
});
});
}

//低版本IE处理方式,不支持跨域
,iframeSend = function(){
var iframe = $('#'+ ELEM_IFRAME);

that.elemFile.parent().submit();

//获取响应信息
clearInterval(Class.timer);
Class.timer = setInterval(function() {
var res, iframeBody = iframe.contents().find('body');
try {
res = iframeBody.text();
} catch(e) {
that.msg('获取上传后的响应信息出现异常');
clearInterval(Class.timer);
error();
}
if(res){
clearInterval(Class.timer);
iframeBody.html('');
done(0, res);
}
}, 30);
}

//统一回调
,done = function(index, res){
that.elemFile.next('.'+ ELEM_CHOOSE).remove();
elemFile.value = '';
if(typeof res !== 'object'){
try {
res = JSON.parse(res);
} catch(e){
res = {};
return that.msg('请对上传接口返回有效JSON');
}
}
typeof options.done === 'function' && options.done(res, index || 0, function(files){
that.upload(files);
});
}
//--------------ajax多附件上传进度条--------------
,xhr = function(index, e){
typeof options.xhr === 'function' && options.xhr(index || 0,e);
}
//--------------ajax多附件上传进度条--------------

//统一网络异常回调
,error = function(index){
if(options.auto){
elemFile.value = '';
}
typeof options.error === 'function' && options.error(index || 0, function(files){
that.upload(files);
});
}

,exts = options.exts
,check ,value = function(){
var arr = [];
layui.each(files || that.chooseFiles, function(i, item){
arr.push(item.name);
});
return arr;
}()

//回调返回的参数
,args = {
preview: function(callback){
that.preview(callback);
}
,upload: function(index, file){
var thisFile = {};
thisFile[index] = file;
that.upload(thisFile);
}
,pushFile: function(){
that.files = that.files || {};
layui.each(that.chooseFiles, function(index, item){
that.files[index] = item;
});
return that.files;
}
}

//提交上传
,send = function(){
if(type === 'choose'){
return options.choose && options.choose(args);
}

//上传前的回调
options.before && options.before(args);

//IE兼容处理
if(device.ie){
return device.ie > 9 ? ajaxSend() : iframeSend();
}

ajaxSend();
}

//校验文件格式
value = value.length === 0
? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '')
: value;

if(value.length === 0) return;

switch(options.accept){
case 'file': //一般文件
if(exts && !RegExp('\\w\\.('+ exts +')$', 'i').test(escape(value))){
that.msg('选择的文件中包含不支持的格式');
return elemFile.value = '';
}
break;
case 'video': //视频文件
if(!RegExp('\\w\\.('+ (exts || 'avi|mp4|wma|rmvb|rm|flash|3gp|flv') +')$', 'i').test(escape(value))){
that.msg('选择的视频中包含不支持的格式');
return elemFile.value = '';
}
break;
case 'audio': //音频文件
if(!RegExp('\\w\\.('+ (exts || 'mp3|wav|mid') +')$', 'i').test(escape(value))){
that.msg('选择的音频中包含不支持的格式');
return elemFile.value = '';
}
break;
default: //图片文件
layui.each(value, function(i, item){
if(!RegExp('\\w\\.('+ (exts || 'jpg|png|gif|bmp|jpeg$') +')', 'i').test(escape(item))){
check = true;
}
});
if(check){
that.msg('选择的图片中包含不支持的格式');
return elemFile.value = '';
}
break;
}

//检验文件数量
that.fileLength = function(){
var length = 0
,items = files || that.files || that.chooseFiles || elemFile.files;
layui.each(items, function(){
length++;
});
return length;
}();
if(options.number && that.fileLength > options.number){
return that.msg('同时最多只能上传的数量为:'+ options.number);
}

//检验文件大小
if(options.size > 0 && !(device.ie && device.ie < 10)){
var limitSize;

layui.each(that.chooseFiles, function(index, file){
if(file.size > 1024*options.size){
var size = options.size/1024;
size = size >= 1
? (Math.floor(size) + (size%1 > 0 ? size.toFixed(1) : 0)) + 'MB'
: options.size + 'KB'
elemFile.value = '';
limitSize = size;

}
});
if(limitSize) return that.msg('文件不能超过'+ limitSize);
}
send();
};
2.页面调用

再upload.render 中添加一下代码:
, xhr:function (index,e) {
var percent=e.loaded / e.total;//计算百分比
percent = parseFloat(percent.toFixed(2));//解决小数点问题
element.progress('progress_'+index+'', percent*100+'%');
console.log("-----"+percent);
}
效果图:


上个完整代码:
下载地址:https://pan.baidu.com/s/1MgOwF0wQPI7gLr7sMcpmwg
回帖
  • 收藏收藏···········
    1 回复
  • 非常感谢楼主无私分享
    1 回复
  • 对于第三方云存储,进度条是有问题的,本地没问题。不知有没解决方案。测试了 七牛云 阿里云 存储
    1 回复
  • 厉害了,楼主[good]
    1 回复
  • 永远
    5天前
    @MrDream 任何版本都可以 需要下载源码单独改 按照帖子的方式修改就行了
    1 回复
  • 永远
    5天前
    @吉他手 没有做可运行的例子,我贴的有jsp的。后台代码写个上次附件的代码jsp应该能运行
    1 回复
  • 厉害了,点赞
    0 回复
  • 收藏收藏,谢谢分享
    0 回复
  • 大王
    2018-5-16
    感谢分享[good]
    0 回复
  • MrDream
    2018-5-19
    什么版本的layui可用?
    0 回复
  • 楼主能发一个 完整的代码吗 直接可以运行的?
    0 回复