PageSourceSearch

https://www.shiniteknife.com/js/Huploadify-V2.1.1/jquery.Huploadify.js

js shiniteknife.com collected 2026-10-04 04:54:21 UTC 19,639 bytes, 536 lines download raw bytes

1/*
2Huploadify
3version : 2.1.1
4author : 吕大豹
5publish date : 2014/01/27
6site : http://www.cnblogs.com/lvdabao
7*/
8(function($){
9$.fn.Huploadify = function(opts){
10	var itemTemp = '<div id="${fileID}" class="uploadify-queue-item"><div class="uploadify-progress"><div class="uploadify-progress-bar"></div></div><span class="up_filename">${fileName}</span><span class="uploadbtn">上传</span><span class="delfilebtn">删除</span></div>';
11	var defaults = {
12		fileTypeExts:'*.*',//允许上传的文件类型,格式'*.jpg;*.doc'
13		uploader:'',//文件提交的地址
14		auto:false,//是否开启自动上传
15		method:'post',//发送请求的方式,get或post
16		multi:false,//是否允许选择多个文件
17		formData:{},//发送给服务端的参数,格式:{key1:value1,key2:value2}
18		fileObjName:'file',//在后端接受文件的参数名称,如PHP中的$_FILES['file']
19		fileSizeLimit:2048,//允许上传的文件大小,单位KB
20		showUploadedPercent:true,//是否实时显示上传的百分比,如20%
21		showUploadedSize:false,//是否实时显示已上传的文件大小,如1M/2M
22		buttonText:'选择文件',//上传按钮上的文字
23		removeTimeout: 1,//上传完成后进度条的消失时间
24		itemTemplate:itemTemp,//上传队列显示的模板
25		breakPoints:false,//是否开启断点续传
26		fileSplitSize:1024*1024,//断点续传的文件块大小,单位Byte,默认1M
27		getUploadedSize:null,//类型:function,自定义获取已上传文件的大小函数,用于开启断点续传模式,可传入一个参数file,即当前上传的文件对象,需返回number类型
28		saveUploadedSize:null,//类型:function,自定义保存已上传文件的大小函数,用于开启断点续传模式,可传入两个参数:file:当前上传的文件对象,value:已上传文件的大小,单位Byte
29		saveInfoLocal:false,//用于开启断点续传模式,是否使用localStorage存储已上传文件大小
30		onUploadStart:null,//上传开始时的动作
31		onUploadSuccess:null,//上传成功的动作
32		onUploadComplete:null,//上传完成的动作
33		onUploadError:null, //上传失败的动作
34		onInit:null,//初始化时的动作
35		onCancel:null,//删除掉某个文件后的回调函数,可传入参数file
36		onSelect:null//选择文件后执行的动作,可传入参数files,文件列表
37	}
38
39	var option = $.extend(defaults,opts);	
40    if(option.auto){
41	
42	}
43	//将文件的单位由bytes转换为KB或MB,若第二个参数指定为true,则永远转换为KB
44	var formatFileSize = function(size,byKB){
45		if (size> 1024 * 1024&&!byKB){
46			size = (Math.round(size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
47		}
48		else{
49			size = (Math.round(size * 100 / 1024) / 100).toString() + 'KB';
50		}
51		return size;
52	}
53	//根据文件序号获取文件
54	var getFile = function(index,files){
55		for(var i=0;i<files.length;i++){	   
56		  if(files[i].index == index){
57			  return files[i];
58			}
59		}
60		return false;
61	}
62	
63	//将输入的文件类型字符串转化为数组,原格式为*.jpg;*.png
64	var getFileTypes = function(str){
65		var result = [];
66		var arr1 = str.split(";");
67		for(var i=0,len=arr1.length;i<len;i++){
68			result.push(arr1[i].split(".").pop());
69		}
70		return result;
71	}
72
73	var mimetypeMap = {
74		zip : ['application/x-zip-compressed'],
75		jpg : ['image/jpeg'],
76		png : ['image/png'],
77		gif : ['image/gif'],
78		doc : ['application/msword'],
79		xls : ['application/msexcel'],
80		docx : ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
81		xlsx : ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
82		ppt : ['application/vnd.ms-powerpoint '],
83		pptx : ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
84		mp3 : ['audio/mp3'],
85		mp4 : ['video/mp4'],
86		pdf : ['application/pdf']
87	};
88
89	//根据后缀名获得文件的mime类型
90	var getMimetype = function(name){
91		return mimetypeMap[name];
92	}
93
94	//根据配置的字符串,获得上传组件accept的值
95	var getAcceptString = function(str){
96		var types = getFileTypes(str);
97		var result = [];
98		for(var i=0,len=types.length;i<len;i++){
99			var mime = getMimetype(types[i]);
100			if(mime){
101				result.push(mime);				
102			}
103		}
104		return result.join(',');
105	}
106
107	//发送文件块函数
108	var sendBlob = function(url,xhr,file,formdata){
109		console.log(888);
110	 	xhr.open(option.method, url, true);
111		xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
112		var fd = new FormData();
113		fd.append(option.fileObjName,file);
114		if(formdata){
115	  	for(key in formdata){
116	  		fd.append(key,formdata[key]);
117	  	}
118	  }
119		xhr.send(fd);
120	}
121
122	var fileObj = null;
123
124	this.each(function(){
125		var _this = $(this);
126		var cname='uploadify-button';
127		var ctxt=option.buttonText;
128		if($(this).attr("id")=='cell-uppic-btn'){
129			cname='uploadify-button uploadify-button-2';
130			ctxt='';
131		}
132		//先添加上file按钮和上传列表
133		var instanceNumber = $('.uploadify').length+1;
134		var inputStr = '<input id="select_btn_'+instanceNumber+'" class="selectbtn" style="display:none;" type="file"  name="fileselect[]"';
135		inputStr += option.multi ? ' multiple' : '';
136		inputStr += ' accept="';
137		inputStr += getAcceptString(option.fileTypeExts);
138		inputStr += '"/>';
139		inputStr += '<a id="file_upload_'+instanceNumber+'-button" href="javascript:void(0)" class="'+cname+'">';
140		inputStr += ctxt;
141		inputStr += '</a>';
142		var uploadFileListStr = '<div id="file_upload_'+instanceNumber+'-queue" class="uploadify-queue"></div>';
143		_this.append(inputStr+uploadFileListStr);	
144		
145		
146		//创建文件对象
147	  fileObj = {
148	  	uploadAllowed: true,
149		  fileInput: _this.find('.selectbtn'),				//html file控件
150		  uploadFileList : _this.find('.uploadify-queue'),
151		  container : _this, //上传控件的外层div引用
152		  url: option.uploader,						//ajax地址
153		  fileFilter: [],					//过滤后的文件数组
154		  uploadOver:true, //一次上传是否真正结束,用于断点续传的情况
155		  filter: function(files) {		//选择文件组的过滤方法
156			  var arr = [];
157			  var typeArray = getFileTypes(option.fileTypeExts);
158			  if(typeArray.length>0){
159				  for(var i=0,len=files.length;i<len;i++){
160				  	var thisFile = files[i];
161					console.log(option.uploader);
162			  		if(parseInt(formatFileSize(thisFile.size,true))>option.fileSizeLimit){
163			  			alert('文件'+thisFile.name+'大小超出限制!');
164			  			continue;
165			  		}
166						if($.inArray(thisFile.name.split('.').pop().toLowerCase(),typeArray)>=0 || $.inArray('*', typeArray)>=0){
167							arr.push(thisFile);	
168						}
169						else{
170							alert('文件'+thisFile.name+'类型不允许!');
171						}  	
172					}	
173				}
174			  return arr;  	
175		  },
176		  //文件选择后
177		  funSelect: function(files){
178			console.log(9999);
179				for(var i=0,len=files.length;i<len;i++){
180					var file = files[i];
181					if(/.*[\u4e00-\u9fa5]+.*$/.test(file.name)) { 
182						alert('对不起,图片名称不能包含中文');
183                    }else{
184					    //处理模板中使用的变量
185					    var $html = $(option.itemTemplate.replace(/\${fileID}/g,'fileupload_'+instanceNumber+'_'+file.index).replace(/\${fileName}/g,file.name).replace(/\${fileSize}/g,formatFileSize(file.size)).replace(/\${instanceID}/g,_this.attr('id')));
186					    //如果是自动上传,去掉上传按钮
187					    if(option.auto){
188						    $html.find('.uploadbtn').remove();
189					    }
190					    //如果开启断点续传,先初始化原来上传的文件大小
191					    var initWidth = 0,initFileSize = '0KB',initUppercent = '0%';
192					    option.breakPoints=false;//my
193					    if(option.breakPoints){
194						    var uploadedSize = this.funGetUploadedSize(file);	
195				  	        //先设置进度条为原来已上传的文件大小
196				  	        initWidth = (uploadedSize / file.size * 100) + '%';
197				  	        initFileSize = formatFileSize(uploadedSize);
198				  	        initUppercent = (uploadedSize / file.size * 100).toFixed(2) + '%';
199console.log(3234242422);
200				  	        $html.find('.uploadify-progress-bar').css('width',initWidth);
201					    }
202
203					    this.uploadFileList.append($html);
204					
205					    //判断是否显示已上传文件大小
206					    if(option.showUploadedSize){
207						    var num = '<span class="progressnum"><span class="uploadedsize">'+initFileSize+'</span>/<span class="totalsize">${fileSize}</span></span>'.replace(/\${fileSize}/g,formatFileSize(file.size));
208						    $html.find('.uploadify-progress').after(num);
209					    }
210					
211					    //判断是否显示上传百分比	
212					    if(option.showUploadedPercent){
213						    var percentText = '<span class="up_percent">'+initUppercent+'</span>';
214						    $html.find('.uploadify-progress').after(percentText);
215					    }
216					    option.onSelect&&option.onSelect(files);
217
218					    //判断是否是自动上传
219					    if(option.auto){
220						    console.log(2412142314);
221						    this.funUploadFile(file);
222					    }
223					    else{
224							console.log(4243324234);
225						    //如果配置非自动上传,绑定上传事件
226					 	    $html.find('.uploadbtn').on('click',(function(file){
227					 			return function(){fileObj.funUploadFile(file);}
228					 		})(file));
229					    }
230					    //为删除文件按钮绑定删除文件事件
231			 		    $html.find('.delfilebtn').on('click',(function(file){
232					 			return function(){fileObj.funDeleteFile(file.index);}
233					 		})(file));
234					}
235			 	}
236
237			 
238			},				
239		  onProgress: function(file, loaded, total) {
240				var eleProgress = _this.find('#fileupload_'+instanceNumber+'_'+file.index+' .uploadify-progress');
241
242				var thisLoaded = loaded;
243				//根据上一次触发progress时上传的大小,得到本次的增量
244				var lastLoaded = eleProgress.attr('lastLoaded') || 0;
245				loaded -= parseInt(lastLoaded);
246
247				var progressBar = eleProgress.children('.uploadify-progress-bar');
248				var oldWidth = option.breakPoints ? parseFloat(progressBar.get(0).style.width || 0) : 0;
249				var percent = (loaded / total * 100 + oldWidth).toFixed(2);
250
251				var percentText = percent > 100 ? '99.99%' : percent+'%';//校正四舍五入的计算误差
252				if(option.showUploadedSize){
253					eleProgress.nextAll('.progressnum .uploadedsize').text(formatFileSize(loaded));
254					eleProgress.nextAll('.progressnum .totalsize').text(formatFileSize(total));
255				}
256				if(option.showUploadedPercent){
257					eleProgress.nextAll('.up_percent').text(percentText);	
258				}
259
260				progressBar.css('width',percentText);
261
262				//记录本次触发progress时已上传的大小,用来计算下次需增加的数量
263				if(thisLoaded<option.fileSplitSize){
264					eleProgress.attr('lastLoaded',thisLoaded);
265				}
266				else{
267					eleProgress.removeAttr('lastLoaded');	
268				}
269
270	  	},		//文件上传进度
271
272		  /* 开发参数和内置方法分界线 */
273
274		  //获取当前进度条的宽度,返回字符串如90%
275		  funGetProgressWidth: function(index){
276		  	var eleProgressBar = _this.find('#fileupload_'+instanceNumber+'_'+index+' .uploadify-progress-bar');
277		  	return eleProgressBar.get(0).style.width || '';
278		  },
279
280		  //获取已上传的文件片大小,当开启断点续传模式
281		  funGetUploadedSize: function(file){
282		  	if(option.getUploadedSize){
283		  		return option.getUploadedSize(file);
284		  	}
285		  	else{
286		  		if(option.saveInfoLocal){
287		  			return parseInt(localStorage.getItem(file.name)) || 0;	
288		  		}
289		  	}
290		  },
291
292		  funSaveUploadedSize: function(file,value){
293		  	if(option.saveUploadedSize){
294		  		option.saveUploadedSize(file,value);
295		  	}
296		  	else{
297		  		if(option.saveInfoLocal){
298		  			localStorage.setItem(file.name,value);		
299		  		}
300		  	}
301		  },
302		  
303		  //获取选择文件,file控件
304		  funGetFiles: function(e) {	  
305			  // 获取文件列表对象
306			  var files = e.target.files;
307			  //继续添加文件
308			  files = this.filter(files);
309			  for(var i=0,len=files.length;i<len;i++){
310			  	this.fileFilter.push(files[i]);	
311			  }
312			  this.funDealFiles(files);
313			  return this;
314		  },
315		  
316		  //选中文件的处理与回调
317		  funDealFiles: function(files) {
318			  var fileCount = _this.find('.uploadify-queue .uploadify-queue-item').length;//队列中已经有的文件个数
319			  for(var i=0,len=files.length;i<len;i++){
320				  files[i].index = ++fileCount;
321				  files[i].id = 'fileupload_'+instanceNumber+'_'+files[i].index;
322				  }
323			  //执行选择回调
324			  this.funSelect(files);
325			  
326			  return this;
327		  },
328		  
329		  //删除对应的文件
330		  funDeleteFile: function(index) {
331			  for (var i = 0,len=this.fileFilter.length; i<len; i++) {
332					  var file = this.fileFilter[i];
333					  if (file.index == index) {
334					  	if(option.breakPoints){
335					  		this.uploadAllowed = false;
336					  	}
337						  this.fileFilter.splice(i,1);
338						  _this.find('#fileupload_'+instanceNumber+'_'+index).fadeOut();
339						  fileObj.fileInput.val('');
340						  option.onCancel&&option.onCancel(file);	
341						  break;
342					  }
343			  }
344			  return this;
345		  },
346		  
347		  //文件上传
348		  funUploadFile: function(file) {
349			  var xhr = false;
350			  var originalFile = file;//保存原始为切割的文件
351			  var thisfile = _this.find('#fileupload_'+instanceNumber+'_'+file.index);
352			  var regulateView = function(){
353			  	if(fileObj.uploadOver){
354			  		thisfile.find('.uploadify-progress-bar').css('width','100%');
355						option.showUploadedSize&&thisfile.find('.uploadedsize').text(thisfile.find('.totalsize').text());
356						option.showUploadedPercent&&thisfile.find('.up_percent').text('100%');	
357			  	}
358			  }//校正进度条和上传比例的误差
359
360			  try{
361				 xhr=new XMLHttpRequest();//尝试创建 XMLHttpRequest 对象,除 IE 外的浏览器都支持这个方法。
362			  }catch(e){	  
363				xhr=ActiveXobject("Msxml12.XMLHTTP");//使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)。
364			  }
365
366			  if(option.breakPoints){
367			  	var fileName = file.name,fileId = file.id,fileIndex = file.index, fileSize = file.size;//先保存原来的文件名称
368			  	var uploadedSize = parseInt(this.funGetUploadedSize(originalFile));	
369			  	//对文件进行切割,并保留原来的信息			  	
370			  	file = originalFile.slice(uploadedSize,uploadedSize + option.fileSplitSize);
371			  	file.name = fileName;file.id = fileId;file.index =  fileIndex;
372			  }
373			  			  console.log(33333);
374			  if (xhr.upload && uploadedSize !== false) {
375				  // 上传中
376				  xhr.upload.addEventListener("progress", function(e) {
377					  fileObj.onProgress(file, e.loaded, originalFile.size);
378				  }, false);
379	  
380				  console.log(4444);
381				  console.log( xhr);
382				  // 文件上传成功或是失败
383				  xhr.onreadystatechange = function(e) {
384					console.log(5555);
385					console.log(xhr.readyState);
386					  if (xhr.readyState == 4) {
387					  	fileObj.uploadOver = true;
388						  if (xhr.status == 200) {
389							
390								var returnData = xhr.responseText ? JSON.parse(xhr.responseText) : {} ;
391								//将文件块数据更新到本地记录
392								if(option.breakPoints){
393									//更新已上传文件大小,保存到本地
394									uploadedSize += option.fileSplitSize;
395									fileObj.funSaveUploadedSize(originalFile,uploadedSize);	
396									//继续上传其他片段
397									if(uploadedSize<fileSize){
398										fileObj.uploadOver = false;
399										if(fileObj.uploadAllowed){
400											file = originalFile.slice(uploadedSize,uploadedSize + option.fileSplitSize);
401									  	file.name = fileName;file.id = fileId;file.index = fileIndex;file.size = fileSize;
402											sendBlob(fileObj.url,xhr,file,option.formData);	
403										}
404									}
405									else{
406										regulateView();
407									}
408								}
409								else{
410									regulateView();
411								}
412									
413								if(fileObj.uploadOver){
414									option.onUploadSuccess&&option.onUploadSuccess(originalFile, xhr.responseText);
415								  //在指定的间隔时间后删掉进度条
416								 
417									//console.log('fileupload_'+instanceNumber+'_'+originalFile.index);
418								  	_this.find('#fileupload_'+instanceNumber+'_'+originalFile.index).fadeOut();
419								  	
420								}
421							  
422						  } else {
423							console.log(666);
424							  fileObj.uploadOver&&option.onUploadError&&option.onUploadError(originalFile, xhr.responseText);		
425						  }
426
427						  if (fileObj.uploadOver) {
428						  	option.onUploadComplete&&option.onUploadComplete(originalFile,xhr.responseText);
429							  //清除文件选择框中的已有值
430							  fileObj.fileInput.val('');	
431						  };
432						  
433					  }
434				  };
435	  
436				  console.log(7777);
437				  console.log(option.onUploadStart());
438	  			option.onUploadStart&&option.onUploadStart();	
439				  // 开始上传
440 				  //option.formData['file_name'] = originalFile.name;
441				  //option.formData['last_time'] = originalFile.lastModifiedDate.getTime();
442
443				  option.formData.fileName = originalFile.name;
444				  option.formData.lastModifiedDate = originalFile.lastModifiedDate.getTime();
445				  fileObj.uploadAllowed = true;//重置允许上传为true
446				  sendBlob(this.url,xhr,file,option.formData);
447			  }	
448		  },
449		  
450		  init: function() {	  
451			  //文件选择控件选择
452			  if (this.fileInput.length>0) {
453				  this.fileInput.change(function(e) { 
454				  	fileObj.funGetFiles(e); 
455				  });	
456			  }
457			  
458			  //点击上传按钮时触发file的click事件
459			  _this.find('.uploadify-button').on('click',function(){
460				  _this.find('.selectbtn').trigger('click');
461				});
462			  
463			  option.onInit&&option.onInit();
464		  }
465  	};
466		//初始化文件对象
467		fileObj.init();
468
469	}); 
470
471	var returnObj =  {
472		stop : function(){
473  		fileObj.uploadOver = false;
474			fileObj.uploadAllowed = false;
475		},
476		upload : function(fileIndex){
477			if(fileIndex === '*'){
478				for(var i=0,len=fileObj.fileFilter.length;i<len;i++){
479					fileObj.funUploadFile(fileObj.fileFilter[i]);
480				}
481			}
482			else{
483				var file = getFile(fileIndex,fileObj.fileFilter);
484				file && fileObj.funUploadFile(file);	
485			}
486		},
487		cancel : function(fileIndex){
488			if(fileIndex === '*'){
489				for(var i=0,len=fileObj.fileFilter.length;i<len;i++){
490					fileObj.funDeleteFile(++i);
491				}
492			}
493			else{
494				fileObj.funDeleteFile(fileIndex);	
495			}
496		},
497		disable : function(instanceID){
498			var parent = instanceID ? $('file_upload_'+instanceID+'-button') : $('body');
499			parent.find('.uploadify-button').css('background-color','#888').off('click');
500		},
501		ennable : function(instanceID){
502			//点击上传按钮时触发file的click事件
503			var parent = instanceID ? $('file_upload_'+instanceID+'-button') : $('body');
504		  	parent.find('.uploadify-button').css('background-color','#707070').on('click',function(){
505			parent.find('.selectbtn').trigger('click');
506			});
507		},
508		destroy : function(){
509			fileObj.container.html('');
510		},
511		settings : function(name,value){
512			if(arguments.length==1){
513				return option[name];
514			}
515			else{
516				if(name=='formData'){
517					option.formData = $.extend(option.formData, value);
518				}
519				else{
520					option[name] = value;
521				}
522			}
523		},
524		Huploadify : function(){
525			var method = arguments[0];
526			if(method in this){
527				Array.prototype.splice.call(arguments, 0, 1);
528				this[method].apply(this[method], arguments);
529			}
530		}
531	};
532	
533	return returnObj;
534}	
535
536})(jQuery)

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.