先說說爲啥要擴展?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', });