先说说为啥要扩展?javascript
webupload是百度团队开源的一块很是优秀的上传插件提供分片、并发、压缩等(http://fex.baidu.com/webuploader/),不提供界面ui须要用户本身设计界面。个人需求是一个页面须要动态建立多个webupload对象,这就形成了页面须要写n多行dom操做代码。清除对象时须要预先用全局变量存储动态建立的对象,这代码写着写着就变臃肿了,因此就扩展成一个jquery插件的形式。css
先来点效果再上代码,没精力折腾了,敲完撤。html
代码有css js 和图片 css固然是拷贝抄袭精简别人的了html5
ext-webuploader.jsjava
/** * webUpload扩展 */ ;(function($,$window) { //定义全局类 var UploadExt = $window.UploadExt ||{ extList:{}//extObj对象集合 }; $window.UploadExt = UploadExt; //定义ExtObj类构造器 function ExtObj(id,opt){ this.id=id, this.defaults = { id:"", //当前上传容器惟一标示 name:"", //文件上传成功后文件路径接收域name值 pathValues:"", //文件路径 type:"file", //类型 file 或是 image,默认 file readOnly:false, //是否只读, 只读不显示选择文件按钮,只显示 pathValues对应的文件 auto:false, //是否自动上传 params:"", //这是上传时须要传递的参数,拼接url后面多个参数以&分隔 extendParams:{}, //这是每一个文件上传时候须要传递的参数,相似 css 写法 buttonStyle:"btn-green btn-S", //按钮颜色和大小 默认-绿色小号 fileNumLimit:3, //上传最大文件数 fileSingleSizeLimit:5*1024*1024,//单个文件大小限制(单位- [B]) duplicate:true, //去重, 根据文件名字、文件大小和最后修改时间来生成 hash Key extensions:null, //认许文件后缀名 buttonText:"选择文件", //控件按钮显示文本 fileVal:"file", //文件上传域的name值 url:"webUpload.do", //上传url downloadUrl:"webDownload.do?dbPath=",//默认下载地址 onSuccess:function(file,response){}, //上传成功后的回调函数 }, this.options = $.extend({}, this.defaults, opt); } /** * 添加 获取/构建 extObj对象 */ UploadExt.getExtObj = function(id,opt){ var obj = this.extList[id]; if (!obj && opt) {//不存在则经过参数建立对象 //不存在则经过jquery插件方法构造extObj对象 obj = extList[id] =$("#"+id).extWebUploader(opt); } return obj; }; /** * 销毁百度webupload上传对象 */ UploadExt.destroy = function(id){ var obj = this.extList[id]; if (obj) { obj.uploader.destroy(); delete this.extList[id]; } }; //扩展jquery元素方法 $.fn.extWebUploader = function(opt,paramObj) { Array.prototype.removeItem = function(val) {//给array对象添加方法 var index = this.indexOf(val); if (index > -1) { this.splice(index, 1); } }; //缩略图大小暂时写死,也能够修改css var ratio = $window.devicePixelRatio || 1; var thumbnailWidth = 100 * ratio; var thumbnailHeight = 100 * ratio; //随机数 var randomFor = function(n) { var rnd = ''; for (var i = 0; i < n; i++) { rnd += Math.floor(Math.random() * 10); } return rnd; }; /** * 检测是否支持base64 */ var isSupportBase64 = function() { var data = new Image(); var support = true; data.onload = data.onerror = function() { if (this.width != 1 || this.height != 1) { support = false; } } return support; }; var getHtml = function(type,id,name,size){ var html1="<div class='dz-preview' id='"+id+"' >"; var html2img=" <div class='img-details'>"; var html2file=" <div class='file-details'>"; var html3="" + " <div class='dz-filename'>"+ " <span>"+ name +"</span>"+ " </div>"+ " <div class='dz-size' data-dz-size=''>"+ "" + size + " </div> "; var html4=" <img src='' />"; var html5="" + " <div class='dz-progress' style='display:block;'>"+ " <div class='progress'>"+ " <div class='progress-bar progress-bar-success progress-bar-striped active' role='progressbar' " + " aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='width:0%'></div>"+ " </div>"+ " </div>"+ " <div class='dz-error-message'>"+ " <span data-dz-errormessage=''></span>"+ " </div>"+ " </div>"+ " <div class='dz-success-mark'></div>"+ " <div class='dz-error-mark'></div> "+ " <div class='del-btn' data-path=''>删除</div>"+ "</div>"; var img_preview = html1 + html2img + html3 + html4 + html5; var file_preview= html1 + html2file + html3 + html5; if(type=="image"){ return img_preview; }else{ return file_preview; } }; //换算大小值 var getSize = function(size){ if(size>1024*1024*1024){ var val = Math.round((size/(1024*1024*1024))*100)/100; return "<strong>"+val+"</strong> GB"; }else if(size>1024*1024){ var val = Math.round((size/(1024*1024))*100)/100; return "<strong>"+val+"</strong> MB"; }else if(size>1024){ var val = Math.round((size/1024)*100)/100; return "<strong>"+val+"</strong> KB"; }else if(size>1024){ var val = Math.round(size*100)/100; return "<strong>"+val+"</strong> B"; }else{ return "<strong>---</strong>"; } }; //拆分文件名 var mygetFileName = function(filepath) { if (filepath.lastIndexOf('\\') > 0) { return filepath.substring(filepath.lastIndexOf('\\') + 1); } else if (filepath.lastIndexOf('/') > 0) { return filepath.substring(filepath.lastIndexOf('/') + 1); } else { return filepath; } }; //初始化jquery元素集,return方便链式调用 return this.each(function() { var oo = $(this); var ooId=oo.attr("id");//获取当前容器id var extObj; //显示上传图片 var showImg = function(src, id) { if (extObj.options['type']=="image") { $("#"+extObj.options['id']+id+" .img-details img").attr("src",src); } }; //添加文件dom var addFileDom = function(file) { var $list = $('#'+extObj.options['id']+'_thelist'); var id = extObj.options['id'] + file.id; var name = file.name; var size = file.size; if(extObj.options['fileNumLimit']==1){ oo.prepend(getHtml(extObj.options['type'],id,name,size)); }else{//多个文件 $list.append(getHtml(extObj.options['type'],id,name,size)); } //绑定删除事件 $("#"+extObj.options['id'] + file.id +" .del-btn").on('click',function() { var optpath = $("#"+extObj.options['id'] + file.id +" .del-btn").attr("data-path"); if(optpath){ $.post('webUpload.do',{path:optpath,isdel: "1"},function(data) { if (data.success) { extObj['exsitPathArr'].removeItem(optpath); $("#"+extObj.options['id'] + file.id).remove();//删除dom $name = $('#'+extObj.options['id'] + " .fordel input[name='"+extObj.options['name']+"']"); if ($name.length) { $name.val(extObj['exsitPathArr'].join(",")); } if(file.type){ extObj['uploader'].removeFile(file.id);//移除文件 } } },'JSON'); }else{ $("#"+extObj.options['id'] + file.id).remove();//删除dom extObj['uploader'].removeFile(file.id);//移除文件 if(file.type){ extObj['uploader'].removeFile(file.id);//移除文件 } } }); // //绑定下载事件 // $("#"+extObj.options['id'] + file.id +" .down-btn").on('click',function() { // var optpath = $('#'+extObj.options['id'] + file.id + " input[name='"+extObj.options['name']+"']").val(); // if(optpath){ // var downsrc = extObj.options['downloadUrl'] + optpath + '&down=1'; // location.href = downsrc; // } // } }; //先判断对象是否初始化过 if(UploadExt.extList[ooId]){ extObj = UploadExt.extList[ooId]; //调用对应方法 if("getObj"==opt){ return extObj.extWebUploader; }else if("addFile"==opt){ //先判断是否超过数量限制 var num = $("#"+ooId+" DIV.dz-preview").length; if(num >= extObj.options['fileNumLimit']){ tip('文件数量超标'); return extObj.extWebUploader; } //第二个参数对象为{path:'/test/stsets/abc.zip'} var path = paramObj.path.replace("\\","\\\\"); extObj['exsitPathArr'].push(path);//将已存在的路径添加到数组中 $name = $('#'+ooId + " .fordel input[name='"+extObj.options['name']+"']"); if (!$name.length) { oo.append( '<div class=\"fordel\"><input type=\"hidden\" name=\"'+extObj.options['name']+'\" value=\"'+path+'\" /></div>' ); }else{ $name.val(extObj['exsitPathArr'].join(",")); } var singleSrc=extObj.options['downloadUrl']+path; var objFile = new Object(); var sizeMatch=paramObj.size.match(/^\d+\.\d+/); var size=paramObj.size.replace(sizeMatch[1],"<strong>"+sizeMatch[1]+"</strong>"); objFile['id']=randomFor(6); objFile['name']=mygetFileName(singleSrc); objFile['size']=size; objFile['Status']='complete';//设置状态为上传完成 addFileDom(objFile); showImg(singleSrc,objFile['id']); $('#'+extObj.options['id'] + objFile['id']).addClass("dz-success"); } }else{//初始化 构建extObj对象 var extObj =new ExtObj(ooId,opt);//oo表示当前操做jquery元素对象 extObj.options['id']= ooId; UploadExt.extList[ooId]=extObj;//将extObj存储在list中 if(extObj.options['fileNumLimit']>1){//上传多个文件,增长list容器 oo.append(" <div id=\""+extObj.options['id']+"_thelist\" class=\"uploader-list\"></div>"); } oo.append(" <div class=\"btns\">" + " <div id=\""+extObj.options['id']+"_pick\">"+extObj.options['buttonText']+"</div>" + " </div>"); //初始化webupload上传组件 var uploader = WebUploader.create({ swf: '/plug-in/webuploader/Uploader.swf', server: extObj.options['url']+"?"+extObj.options['params'], pick: '#'+extObj.options['id']+"_pick", duplicate: extObj.options['duplicate'], resize: false, auto: extObj.options['auto'], fileVal: extObj.options['fileVal'], fileNumLimit: extObj.options['fileNumLimit'], fileSingleSizeLimit: extObj.options['fileSingleSizeLimit'], formData: extObj.options['extendParams'], accept:{ extensions:extObj.options['extensions'] } }); //添加对象属性 webupload对象 extObj['uploader'] =uploader; extObj['extWebUploader']=this;//jquery对象extWebUploader extObj['exsitPathArr']= new Array();//用户存储上传成功的路径数组 //增长按钮样式 $('#'+extObj.options['id']+"_pick").find('div:eq(0)').addClass('webuploader-pick '+extObj.options['buttonStyle']); //手动上传 if(!extObj.options['auto']){ $('#'+extObj.options['id']+"_pick").find('div:eq(0)').after("<div id='"+extObj.options['id']+"ctlBtn' class='upbtn btn-blue "+extObj.options['buttonStyle']+"'>开始上传</div>"); var state = 'pending';//上传状态、当前等待状态 var $btn=$("#"+extObj.options['id']+"ctlBtn"); $btn.on('click', function (){ if (state === 'uploading'){ uploader.stop(); } else { uploader.upload(); } }); uploader.on('all',function (type){ if (type === 'startUpload'){ state = 'uploading'; $btn.text('暂停上传'); }else if (type === 'stopUpload'){ state = 'paused'; $btn.text('开始上传'); } else if (type === 'uploadFinished'){ state = 'done'; $btn.text('开始上传'); } }); } if(extObj.options['readOnly'] || extObj.options['readOnly'] == "readOnly"){ $("#"+extObj.options['id']+"ctlBtn").css('display','none');//隐藏开始上传 $("#"+extObj.options['id']+"_pick").css('display','none');//隐藏选择文件按钮 } var addFile = function(file, filepath) { uploader.makeThumb(file, function(error, src) { if (error) { return false; } if (isSupportBase64()) { if (filepath == '') { showImg(src, file.id); } } else if (filepath != '') { var actSrc = extObj.options['downloadUrl'] + filepath; showImg(actSrc, file.id); } },thumbnailWidth, thumbnailHeight); }; //设置默认值 if(null!=extObj.options['pathValues'] && extObj.options['pathValues'] !="" ){ var pvs = extObj.options['pathValues'].replace("\\","\\\\"); oo.append( '<div class=\"fordel\"><input type=\"hidden\" name=\"'+extObj.options['name']+'\" value=\"'+pvs+'\" /></div>' ); extObj['exsitPathArr']=pvs.split(',');//将默认值按逗号拆分添加到数组中 for(var a = 0; a< extObj['exsitPathArr'].length; a++){ var singlePath=extObj['exsitPathArr'][a]; if(''!=singlePath){ var singleSrc=extObj.options['downloadUrl']+singlePath; var objFile = new Object(); objFile['id']=a; objFile['name']=mygetFileName(singlePath); objFile['Status']='complete';//设置状态为上传完成 objFile['size']="未知"; addFileDom(objFile); showImg(singleSrc,objFile['id']); $("#"+extObj.options['id'] + objFile['id'] +" .del-btn").attr("data-path",singlePath);//添加文件路径 $('#'+extObj.options['id'] + objFile['id']).addClass("dz-success"); } } } //当文件被加入队列以前触发 uploader.on('beforeFileQueued',function(file) { var num = $("#"+extObj.options['id']+" DIV.dz-preview").length; if(num >= extObj.options['fileNumLimit']){ tip('文件数量超标'); return false; } return true; }); //当文件被加入队列之后触发 uploader.on('fileQueued',function(file) { file.size=getSize(file.size);//将size转换 addFileDom(file); addFile(file,""); }); //上传过程当中触发,携带上传进度 uploader.on('uploadProgress',function(file, percentage) { var $div = $('#'+extObj.options['id']+ file.id), $percent = $div.find('.progress .progress-bar'); $percent.css('width', parseInt(percentage * 100)+'%'); $percent.attr("aria-valuenow",parseInt(percentage * 100)); }); //当文件上传成功时触发 uploader.on('uploadSuccess',function(file, response) { if (response.success) { var filepath = response[""+extObj.options['name']+""] || response.obj; extObj['exsitPathArr'].push(filepath);//上传车成功后添加到数组中 $name = $('#'+extObj.options['id'] + " .fordel input[name='"+extObj.options['name']+"']"); if (!$name.length) { oo.append( '<div class=\"fordel\"><input type=\"hidden\" name=\"'+extObj.options['name']+'\" value=\"'+filepath+'\" /></div>' ); }else{ $name.val(extObj['exsitPathArr'].join(",")); } addFile(file, filepath);//若是是图片显示对应图片 $('#'+extObj.options['id'] + file.id).addClass("dz-success"); $("#"+extObj.options['id'] + file.id +" .del-btn").attr("data-path",filepath);//添加文件路径 } else { $('#'+extObj.options['id'] + file.id).addClass("dz-error"); var errorMsg = $('#'+extObj.options['id'] + file.id+" .dz-error-message span"); errorMsg.html("上传出错" + response.msg); errorMsg.data("dz-errormessage","上传出错" + response.msg); } extObj.options.onSuccess(file, response); }); uploader.on('uploadError', function(file, reason) { $('#'+extObj.options['id'] + file.id).addClass("dz-error"); var errorMsg = $('#'+extObj.options['id'] + file.id+" .dz-error-message span"); errorMsg.html("上传出错-code:" + reason); errorMsg.data("dz-errormessage","上传出错-code:" + reason); }); uploader.on('error',function(type) { if (type == 'Q_TYPE_DENIED') { $window.tip('文件类型不识别'); } if (type == 'Q_EXCEED_NUM_LIMIT') { $window.tip('文件数量超标'); } if (type == 'F_DUPLICATE') { $window.tip('相同文件请不要重复上传'); } if (type == 'F_EXCEED_SIZE') { $window.tip('单个文件大小超标'); } if (type == 'Q_EXCEED_SIZE_LIMIT') { $window.tip('文件大小超标'); } }); uploader.on('uploadComplete',function(file) { var $div = $('#'+extObj.options['id']+ file.id).find('.dz-progress'); $div.fadeOut('slow'); }); } }); }; })(jQuery,window);
ext-webuploader.cssjquery
.dz-preview * {box-sizing: border-box;} .dz-preview{ box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.16); font-size: 14px; background: rgba(255, 255, 255, 0.8) none repeat scroll 0 0; border: 1px solid #acacac; display: inline-block; padding: 6px; position: relative; } .dz-preview.file-preview{display:block;} .dz-preview .img-details,.dz-preview .file-details{ background: #ebebeb none repeat scroll 0 0; height: 100px; width: 100px; margin-bottom: 22px; padding: 5px; position: relative; } .dz-preview .file-details{height: 40px;width: 200px;} .dz-preview .dz-filename{ display: block; height: 100%; width:100%; line-height:1.4; word-wrap:break-word; overflow: hidden; } .dz-preview .dz-size{ position:absolute; left:3px; bottom:-28px; height:28px; line-height:28px; overflow: hidden; } .dz-preview .img-details img{ position:absolute; top:0; left:0; width:100%; height:100%; } .dz-preview .img-details:hover img{opacity:0.1;} .dz-preview.dz-error .img-details:hover img{opacity:1;} .dz-preview .dz-progress{ background: #d7d7d7 none repeat scroll 0 0; position: absolute; height:6px; bottom:0px; right:0; left:0; display:none; } .dz-preview.dz-success .dz-progress{display: block;opacity: 0;transition: opacity 0.4s ease-in-out 0s;} .dz-preview .dz-progress .progress{ border-radius:0; height:100%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset; margin-bottom: 20px; overflow: hidden; } .dz-preview .progress-bar-striped,.dz-preview .progress-striped .progress-bar { background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 14px 14px; } .dz-preview .progress-bar.active, .dz-preview .progress.active .progress-bar { animation: 2s linear 0s normal none infinite running progress-bar-stripes; } @-webkit-keyframes progress-bar-stripes { from {background-position: 40px 0;}to {background-position: 0 0;} } @-o-keyframes progress-bar-stripes { from { background-position: 40px 0;}to {background-position: 0 0;} } @keyframes progress-bar-stripes { from {background-position: 40px 0;}to {background-position: 0 0;} } .dz-preview .progress-bar { background-color: #337ab7; box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.15) inset; color: #fff; float: left; font-size: 12px; height: 100%; line-height: 20px; text-align: center; transition: width 0.6s ease 0s; width: 0; } .dz-preview .progress-bar-success { background-color: #5cb85c; } .dz-preview .dz-success-mark, .dz-preview .dz-error-mark{ position: absolute; top: 5px; right: 5px; height: 40px; width: 40px; text-align: center; background-image: url("image/spritemap.png"); background-repeat: no-repeat; display: black; opacity: 0; transition: opacity 0.4s ease-in-out 0s; } .dz-preview .dz-success-mark{background-position: -268px -163px;color: #8cc657;} .dz-preview .dz-error-mark{background-position: -268px -123px;color: #ee162d;} .dz-preview.dz-success .dz-success-mark,.dz-preview.dz-error .dz-error-mark{filter: none;opacity: 1;} .dz-preview .dz-error-message{ position: absolute; left:0px; top:0px; width: 100%; height:100%; background: rgba(245, 245, 245, 0.8) none repeat scroll 0 0; color: #800; padding: 5px 5px; z-index: 0; display:none; } .dz-preview.dz-error .dz-error-message{z-index:10;transition: opacity 0.3s ease-in-out 0s;} .dz-preview.dz-error:hover .dz-error-message{display: block;opacity:0.9;} .dz-preview .del-btn{position:absolute;right:6px;bottom:0px;height:28px;line-height:28px;overflow: hidden; font-size:12px;color: #800;cursor:pointer;}
页面调用代码就很是精简web
//初始化上传组件 $('#content_dom'+index).extWebUploader({ name: 'content', auto:false, type:"image", buttonStyle:'btn-green btn-S', buttonText:'选择图片', fileNumLimit:1, fileSingleSizeLimit:1024*1024*1024*5, //最大5G duplicate:true, fileVal:'file', params:'upType=teachFormFile', });