扩展webupload插件,增加ui界面

先说说为啥要扩展?

webupload是百度团队开源的一块非常优秀的上传插件提供分片、并发、压缩等(http://fex.baidu.com/webuploader/),不提供界面ui需要用户自己设计界面。我的需求是一个页面需要动态创建多个webupload对象,这就造成了页面需要写n多行dom操作代码。清除对象时需要预先用全局变量存储动态创建的对象,这代码写着写着就变臃肿了,所以就扩展成一个jquery插件的形式。

先来点效果再上代码,没精力折腾了,敲完撤。

代码有css js 和图片  css当然是拷贝抄袭精简别人的了

ext-webuploader.js

/**
 * 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.css

.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;}

页面调用代码就非常精简

//初始化上传组件
$('#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', 								
});	

 

转载于:https://my.oschina.net/u/1377077/blog/917409

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值