我们都知道,一般上传文件的实现都是一个一个上传文件实现的,或者通过多添加几个按钮。有没有批量上传呢?肯定是有的,那就是Jquery插件uploadify。Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示。官方提供的实例是php版本的,本文将详细介绍Uploadify插件的运用。
首先是我自己使用的简易的js处理文件
var feng_pic = { uploadTotal : 0, uploadLimit : 25, Max : 25, swf:'', uploader:'', uploadify : function () { //文件上传测试 $('#file').uploadify({ swf : feng_pic.swf, uploader : feng_pic.uploader, uploadLimit : feng_pic.uploadLimit, width : 120, height : 35, fileTypeDesc : '图片类型', buttonCursor : 'pointer', buttonText : '上传图片', fileTypeExts : '*.jpeg; *.jpg; *.png; *.gif', fileSizeLimit : '2MB', removeCompleted : true, removeTimeout : 1, overrideEvents : ['onSelectError','onSelect','onDialogClose','onUploadError'], //上传失败返回的错误 onSelectError : function (file, errorCode, errorMsg) { console.log(file, errorCode, errorMsg); switch (errorCode) { case -100: bootbox.alert("限制为"+feng_pic.Max+"张...", function(){}); break; case -110 : bootbox.alert('超过2MB...', function(){}); break; case -120: bootbox.alert("文件 [" + file.name + "] 大小异常!", function(){}); break; case -130: bootbox.alert("文件 [" + file.name + "] 类型不正确!", function(){}); break; } }, onUploadStart : function () { if (feng_pic.uploadTotal == feng_pic.Max) { $('#file').uploadify('stop'); $('#file').uploadify('cancel'); bootbox.alert("限制为"+feng_pic.Max+"张...", function(){}); } }, //检测FLASH失败调用 onFallback: function () { alert("您未安装FLASH控件,无法上传!请安装FLASH控件后再试。"); }, //图片上传成功回调 onUploadSuccess : function (file, data, response) { var allData = eval('(' + data + ')'); //自定义写的图片上传显示html $('.pic_list').append('<div class="pic_content"><span class="remove"></span><span class="text">删除</span><input type="hidden" name="contractImage[]" value="'+ allData.savename +'"><img src="' + allData.filename + '" class="pic_img"></div>'); setTimeout(function () { feng_pic.hover(); feng_pic.remove(); }, 10); feng_pic.uploadTotal++; feng_pic.uploadLimit--; $('.pic_total').text(feng_pic.uploadTotal); $('.pic_limit').text(feng_pic.uploadLimit); } }); }, hover : function () { var content = $('.pic_content'); var len = content.length; $(content[len - 1]).hover(function () { $(this).find('.remove').show(); $(this).find('.text').show(); }, function () { $(this).find('.remove').hide(); $(this).find('.text').hide(); }); }, allHover:function(){ $('.pic_content').each(function(){ $(this).hover(function () { $(this).find('.remove').show(); $(this).find('.text').show(); }, function () { $(this).find('.remove').hide(); $(this).find('.text').hide(); }); }); }, //删除已上传文件 remove : function () { var remove = $('.pic_content .text'); var len = remove.length; $(remove[len - 1]).on('click', function () { $(this).parent().remove(); feng_pic.uploadTotal--; feng_pic.uploadLimit++; $('.pic_total').text(feng_pic.uploadTotal); $('.pic_limit').text(feng_pic.uploadLimit); var swfu = $('#file').data('uploadify'); var stats = swfu.getStats(); stats.successful_uploads--; swfu.setStats(stats); }); }, allRemove:function(){ $('.pic_content .text').each(function(){ $(this).on('click', function () { $(this).parent().remove(); feng_pic.uploadTotal--; feng_pic.uploadLimit++; $('.pic_total').text(feng_pic.uploadTotal); $('.pic_limit').text(feng_pic.uploadLimit); var swfu = $('#file').data('uploadify'); var stats = swfu.getStats(); stats.successful_uploads--; swfu.setStats(stats); }); }); }, judgeUploadTotal:function(){ var content = $('.pic_content'); var len = content.length; feng_pic.uploadTotal=len; feng_pic.uploadLimit=feng_pic.uploadLimit-len; $('.pic_total').text(feng_pic.uploadTotal); $('.pic_limit').text(feng_pic.uploadLimit); }, //初始化参数 init : function (swf,uploader,uploadLimit) { feng_pic.swf=swf; feng_pic.uploader=uploader; feng_pic.uploadLimit=uploadLimit; feng_pic.Max=uploadLimit; feng_pic.allHover(); feng_pic.allRemove(); feng_pic.judgeUploadTotal(); feng_pic.uploadify(); } };
其次就是HTML与CSS文件(自定义写的)
<!--多文件上传引入--> <script type="text/javascript" src="{_TEMP_PUBLIC_}/uploadFile/js/jquery.ui.js"></script> <link rel="stylesheet" href="{_TEMP_PUBLIC_}/uploadFile/uploadify/uploadify.css"> <link rel="stylesheet" href="{_TEMP_PUBLIC_}/uploadFile/css/feng_upload.css"> <script src="{_TEMP_PUBLIC_}/uploadFile/uploadify/jquery.uploadify.min.js" type="text/javascript"></script> <div class="form-group form-md-line-input"> <label class="col-md-2 control-label">多文件上传</label> <div class="col-md-10"> <div class="postPic"> <div class="pic_header"> <span class="pic_info">共 <span class="pic_total">0</span> 张,还能上传 <span class="pic_limit">0</span> 张(按住ctrl可选择多张,每张最大不能超过2MB)</span> </div> <div class="pic_list"></div> <input type="file" name="file" id="file"> </div> <script type="text/javascript" src="{_TEMP_PUBLIC_}/uploadFile/js/feng_upload.js"></script> <script> $(function(){
//初始化参数 feng_pic.init('{_TEMP_PUBLIC_}/uploadFile/uploadify/uploadify.swf','/index/uploadPhoto.json',25); }); </script> </div> </div>
最后就是CSS文件,主要是上传文件以后的显示样式
.postPic{ border: 1px solid #ccc; height: auto; margin: 1%; border-radius: 4px; padding: 0; } .postPic .pic_header{ height: 30px; line-height: 30px; color: #666; font-size: 13px; background: rgba(204, 204, 204, 0.21); text-indent: 10px; margin-bottom: 20px; box-shadow: 0px 2px 5px 1px rgba(102, 102, 102, 0.42); } .postPic .pic_header .pic_info { float: left; } .pic_total{ height: 30px; line-height: 30px; color: #666; font-size: 13px; background: #fafafa; text-indent: 10px; } .pic_content { width: 140px; height: 140px; float: left; border: 2px solid #eee; margin: 6px 11px; overflow: hidden; position: relative; border-radius: 8px; } .pic_content img{ width: 145px; height: 170px; } #file { clear: both; margin: 0 auto; position: relative; top: 5px; } .text { display: none; width: 140px; height: 25px; line-height: 25px; text-align: center; position: absolute; top: 125px; left: 0; z-index: 3; cursor: pointer; color: #fff; font-size: 13px; } .remove { display: none; width: 140px; height: 25px; background: #000; position: absolute; top: 125px; left: 0; z-index: 2; opacity: 0.7; filter: alpha(opacity=70); cursor: pointer; }
样式图
已上传样式图
给大家看看我给jquery.uploadify.js添加的注释说明
(function($) { // These methods can be called by adding them as the first argument in the uploadify plugin call 这些方法可以被添加在uploadify插件调用的第一个参数 var methods = { init : function(options, swfUploadOptions) { return this.each(function() { // Create a reference to the jQuery DOM object 创建一个对jQuery DOM对象的引用 var $this = $(this); // Clone the original DOM object 克隆原始DOM对象 var $clone = $this.clone(); // Setup the default options 设置默认选项 var settings = $.extend({ // Required Settings 所需的设置 id : $this.attr('id'), // The ID of the DOM object DOM对象的id swf : 'uploadify.swf', // The path to the uploadify SWF file 到Uploadify SWF文件的路径 uploader : 'uploadify.php', // The path to the server-side upload script 服务器端上传脚本的路径 // Options auto : true, // Automatically upload files when added to the queue 自动上传文件时,添加到队列 buttonClass : '', // A class name to add to the browse button DOM object 要添加到浏览按钮DOM对象的类名 buttonCursor : 'hand', // The cursor to use with the browse button 光标与浏览按钮一起使用 buttonImage : null, // (String or null) The path to an image to use for the Flash browse button if not using CSS to style the button (字符串或NULL)的图像的路径使用的Flash浏览按钮,如果不使用CSS风格按钮 buttonText : 'SELECT FILES', // The text to use for the browse button 用于浏览按钮的文本 checkExisting : false, // The path to a server-side script that checks for existing files on the server 检查服务器上现有文件的服务器端脚本的路径 debug : false, // Turn on swfUpload debugging mode 打开swfupload调试模式 fileObjName : 'Filedata', // The name of the file object to use in your server-side script 要在服务器端脚本中使用的文件对象的名称 fileSizeLimit : 0, // The maximum size of an uploadable file in KB (Accepts units B KB MB GB if string, 0 for no limit) 在KB的上传文件的最大大小(KB MB GB单位接受B如果字符串,0为不限制) fileTypeDesc : 'All Files', // The description for file types in the browse dialog 浏览对话框中文件类型的说明 fileTypeExts : '*.*', // Allowed extensions in the browse dialog (server-side validation should also be used) 允许扩展的浏览对话框(服务器端验证也应使用) height : 30, // The height of the browse button 浏览按钮的高度 itemTemplate : false, // The template for the file item in the queue 队列中文件项的模板 method : 'post', // The method to use when sending files to the server-side upload script 将文件发送到服务器端上传脚本时使用的方法 multi : true, // Allow multiple file selection in the browse dialog 允许在浏览对话框中选择多个文件 formData : {}, // An object with additional data to send to the server-side upload script with every file upload 带有附加数据的对象,将每个文件上传到服务器端上传脚本 preventCaching : true, // Adds a random value to the Flash URL to prevent caching of it (conflicts with existing parameters) 添加一个随机值的Flash URL,以防止缓存(与现有参数冲突) progressData : 'percentage', // ('percentage' or 'speed') Data to show in the queue item during a file upload (百分比或速度)在the item to queue日期显示在文件上传 queueID : false, // The ID of the DOM object to use as a file queue (without the #) 对DOM对象的ID作为文件队列(没有#) queueSizeLimit : 999, // The maximum number of files that can be in the queue at one time 一次可以在队列中最多的文件数 removeCompleted : true, // Remove queue items from the queue when they are done uploading 在上传完成时从队列中移除队列项 removeTimeout : 3, // The delay in seconds before removing a queue item if removeCompleted is set to true 延迟秒移除一个队列项目如果removecompleted设置为true之前 requeueErrors : false, // Keep errored files in the queue and keep trying to upload them 错误的文件保持在队列中,继续上传 successTimeout : 30, // The number of seconds to wait for Flash to detect the server's response after the file has finished uploading 在文件完成上传后等待服务器检测服务器响应的秒数 uploadLimit : 0, // The maximum number of files you can upload 您可以上传的文件的最大数量 width : 120, // The width of the browse button 浏览按钮的宽度 // Events overrideEvents : [] // (Array) A list of default event handlers to skip (数组)跳过的默认事件处理程序列表 /* onCancel // Triggered when a file is cancelled from the queue onClearQueue // Triggered during the 'clear queue' method onDestroy // Triggered when the uploadify object is destroyed onDialogClose // Triggered when the browse dialog is closed onDialogOpen // Triggered when the browse dialog is opened onDisable // Triggered when the browse button gets disabled onEnable // Triggered when the browse button gets enabled onFallback // Triggered is Flash is not detected onInit // Triggered when Uploadify is initialized onQueueComplete // Triggered when all files in the queue have been uploaded onSelectError // Triggered when an error occurs while selecting a file (file size, queue size limit, etc.) onSelect // Triggered for each file that is selected onSWFReady // Triggered when the SWF button is loaded onUploadComplete // Triggered when a file upload completes (success or error) onUploadError // Triggered when a file upload returns an error onUploadSuccess // Triggered when a file is uploaded successfully onUploadProgress // Triggered every time a file progress is updated onUploadStart // Triggered immediately before a file upload starts ========================================================================== 两个/触发时,一个文件从队列中取消 onclearqueue /触发“清除队列的方法中 使用/触发时,Uploadify销毁对象 ondialogclose /浏览对话框关闭时触发 ondialogopen /浏览对话框打开时触发 ondisable /触发时,浏览按钮被禁用使/触发时浏览按钮启用 onfallback /触发闪光检测不到 OnInit /触发时,Uploadify被初始化 onqueuecomplete /触发时,队列中的所有文件已上传 onselecterror /触发时发生错误,选择一个文件(文件大小,队列的大小限制,等) onselect /触发每一个文件,选择 onswfready /时触发按钮加载SWF onuploadcomplete /触发文件上传完成时(成功或错误) onuploaderror /触发时,上传文件返回一个错误 onuploadsuccess /触发时,一个文件上传成功 onuploadprogress /触发的每一次进步更新文件 onuploadstart /触发立即上传文件开始之前 */ }, options); // Prepare settings for SWFUpload var swfUploadSettings = { assume_success_timeout : settings.successTimeout, button_placeholder_id : settings.id, button_width : settings.width, button_height : settings.height, button_text : null, button_text_style : null, button_text_top_padding : 0, button_text_left_padding : 0, button_action : (settings.multi ? SWFUpload.BUTTON_ACTION.SELECT_FILES : SWFUpload.BUTTON_ACTION.SELECT_FILE), button_disabled : false, button_cursor : (settings.buttonCursor == 'arrow' ? SWFUpload.CURSOR.ARROW : SWFUpload.CURSOR.HAND), button_window_mode : SWFUpload.WINDOW_MODE.TRANSPARENT, debug : settings.debug, requeue_on_error : settings.requeueErrors, file_post_name : settings.fileObjName, file_size_limit : settings.fileSizeLimit, file_types : settings.fileTypeExts, file_types_description : settings.fileTypeDesc, file_queue_limit : settings.queueSizeLimit, file_upload_limit : settings.uploadLimit, flash_url : settings.swf, prevent_swf_caching : settings.preventCaching, post_params : settings.formData, upload_url : settings.uploader, use_query_string : (settings.method == 'get'), // Event Handlers file_dialog_complete_handler : handlers.onDialogClose, file_dialog_start_handler : handlers.onDialogOpen, file_queued_handler : handlers.onSelect, file_queue_error_handler : handlers.onSelectError, swfupload_loaded_handler : settings.onSWFReady, upload_complete_handler : handlers.onUploadComplete, upload_error_handler : handlers.onUploadError, upload_progress_handler : handlers.onUploadProgress, upload_start_handler : handlers.onUploadStart, upload_success_handler : handlers.onUploadSuccess } // Merge the user-defined options with the defaults if (swfUploadOptions) { swfUploadSettings = $.extend(swfUploadSettings, swfUploadOptions); } // Add the user-defined settings to the swfupload object swfUploadSettings = $.extend(swfUploadSettings, settings); // Detect if Flash is available var playerVersion = swfobject.getFlashPlayerVersion(); var flashInstalled = (playerVersion.major >= 9); if (flashInstalled) { // Create the swfUpload instance window['uploadify_' + settings.id] = new SWFUpload(swfUploadSettings); var swfuploadify = window['uploadify_' + settings.id]; // Add the SWFUpload object to the elements data object $this.data('uploadify', swfuploadify); // Wrap the instance var $wrapper = $('<div />', { 'id' : settings.id, 'class' : 'uploadify', 'css' : { 'height' : settings.height + 'px', 'width' : settings.width + 'px' } }); $('#' + swfuploadify.movieName).wrap($wrapper); // Recreate the reference to wrapper $wrapper = $('#' + settings.id); // Add the data object to the wrapper $wrapper.data('uploadify', swfuploadify); // Create the button var $button = $('<div />', { 'id' : settings.id + '-button', 'class' : 'uploadify-button ' + settings.buttonClass }); if (settings.buttonImage) { $button.css({ 'background-image' : "url('" + settings.buttonImage + "')", 'text-indent' : '-9999px' }); } $button.html('<span class="uploadify-button-text">' + settings.buttonText + '</span>') .css({ 'height' : settings.height + 'px', 'line-height' : settings.height + 'px', 'width' : settings.width + 'px' }); // Append the button to the wrapper $wrapper.append($button); // Adjust the styles of the movie $('#' + swfuploadify.movieName).css({ 'position' : 'absolute', 'z-index' : 1 }); // Create the file queue if (!settings.queueID) { var $queue = $('<div />', { 'id' : settings.id + '-queue', 'class' : 'uploadify-queue' }); $wrapper.after($queue); swfuploadify.settings.queueID = settings.id + '-queue'; swfuploadify.settings.defaultQueue = true; } // Create some queue related objects and variables swfuploadify.queueData = { files : {}, // The files in the queue filesSelected : 0, // The number of files selected in the last select operation filesQueued : 0, // The number of files added to the queue in the last select operation filesReplaced : 0, // The number of files replaced in the last select operation filesCancelled : 0, // The number of files that were cancelled instead of replaced filesErrored : 0, // The number of files that caused error in the last select operation uploadsSuccessful : 0, // The number of files that were successfully uploaded uploadsErrored : 0, // The number of files that returned errors during upload averageSpeed : 0, // The average speed of the uploads in KB queueLength : 0, // The number of files in the queue queueSize : 0, // The size in bytes of the entire queue uploadSize : 0, // The size in bytes of the upload queue queueBytesUploaded : 0, // The size in bytes that have been uploaded for the current upload queue uploadQueue : [], // The files currently to be uploaded errorMsg : 'Some files were not added to the queue:' }; // Save references to all the objects swfuploadify.original = $clone; swfuploadify.wrapper = $wrapper; swfuploadify.button = $button; swfuploadify.queue = $queue; // Call the user-defined init event handler if (settings.onInit) settings.onInit.call($this, swfuploadify); } else { // Call the fallback function if (settings.onFallback) settings.onFallback.call($this); } }); }, // Stop a file upload and remove it from the queue cancel : function(fileID, supressEvent) { var args = arguments; this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'), settings = swfuploadify.settings, delay = -1; if (args[0]) { // Clear the queue if (args[0] == '*') { var queueItemCount = swfuploadify.queueData.queueLength; $('#' + settings.queueID).find('.uploadify-queue-item').each(function() { delay++; if (args[1] === true) { swfuploadify.cancelUpload($(this).attr('id'), false); } else { swfuploadify.cancelUpload($(this).attr('id')); } $(this).find('.data').removeClass('data').html(' - Cancelled'); $(this).find('.uploadify-progress-bar').remove(); $(this).delay(1000 + 100 * delay).fadeOut(500, function() { $(this).remove(); }); }); swfuploadify.queueData.queueSize = 0; swfuploadify.queueData.queueLength = 0; // Trigger the onClearQueue event if (settings.onClearQueue) settings.onClearQueue.call($this, queueItemCount); } else { for (var n = 0; n < args.length; n++) { swfuploadify.cancelUpload(args[n]); /*添加代码--删除队列*/ delete swfuploadify.queueData.files[args[n]]; swfuploadify.queueData.queueLength = swfuploadify.queueData.queueLength - 1; /*添加结束*/ $('#' + args[n]).find('.data').removeClass('data').html(' - Cancelled'); $('#' + args[n]).find('.uploadify-progress-bar').remove(); $('#' + args[n]).delay(1000 + 100 * n).fadeOut(500, function() { $(this).remove(); }); } } } else { var item = $('#' + settings.queueID).find('.uploadify-queue-item').get(0); $item = $(item); swfuploadify.cancelUpload($item.attr('id')); $item.find('.data').removeClass('data').html(' - Cancelled'); $item.find('.uploadify-progress-bar').remove(); $item.delay(1000).fadeOut(500, function() { $(this).remove(); }); } }); }, // Revert the DOM object back to its original state destroy : function() { this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'), settings = swfuploadify.settings; // Destroy the SWF object and swfuploadify.destroy(); // Destroy the queue if (settings.defaultQueue) { $('#' + settings.queueID).remove(); } // Reload the original DOM element $('#' + settings.id).replaceWith(swfuploadify.original); // Call the user-defined event handler if (settings.onDestroy) settings.onDestroy.call(this); delete swfuploadify; }); }, // Disable the select button disable : function(isDisabled) { this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'), settings = swfuploadify.settings; // Call the user-defined event handlers if (isDisabled) { swfuploadify.button.addClass('disabled'); if (settings.onDisable) settings.onDisable.call(this); } else { swfuploadify.button.removeClass('disabled'); if (settings.onEnable) settings.onEnable.call(this); } // Enable/disable the browse button swfuploadify.setButtonDisabled(isDisabled); }); }, // Get or set the settings data settings : function(name, value, resetObjects) { var args = arguments; var returnValue = value; this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'), settings = swfuploadify.settings; if (typeof(args[0]) == 'object') { for (var n in value) { setData(n,value[n]); } } if (args.length === 1) { returnValue = settings[name]; } else { switch (name) { case 'uploader': swfuploadify.setUploadURL(value); break; case 'formData': if (!resetObjects) { value = $.extend(settings.formData, value); } swfuploadify.setPostParams(settings.formData); break; case 'method': if (value == 'get') { swfuploadify.setUseQueryString(true); } else { swfuploadify.setUseQueryString(false); } break; case 'fileObjName': swfuploadify.setFilePostName(value); break; case 'fileTypeExts': swfuploadify.setFileTypes(value, settings.fileTypeDesc); break; case 'fileTypeDesc': swfuploadify.setFileTypes(settings.fileTypeExts, value); break; case 'fileSizeLimit': swfuploadify.setFileSizeLimit(value); break; case 'uploadLimit': swfuploadify.setFileUploadLimit(value); break; case 'queueSizeLimit': swfuploadify.setFileQueueLimit(value); break; case 'buttonImage': swfuploadify.button.css('background-image', settingValue); break; case 'buttonCursor': if (value == 'arrow') { swfuploadify.setButtonCursor(SWFUpload.CURSOR.ARROW); } else { swfuploadify.setButtonCursor(SWFUpload.CURSOR.HAND); } break; case 'buttonText': $('#' + settings.id + '-button').find('.uploadify-button-text').html(value); break; case 'width': swfuploadify.setButtonDimensions(value, settings.height); break; case 'height': swfuploadify.setButtonDimensions(settings.width, value); break; case 'multi': if (value) { swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILES); } else { swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILE); } break; } settings[name] = value; } }); if (args.length === 1) { return returnValue; } }, // Stop the current uploads and requeue what is in progress stop : function() { this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'); // Reset the queue information swfuploadify.queueData.averageSpeed = 0; swfuploadify.queueData.uploadSize = 0; swfuploadify.queueData.bytesUploaded = 0; swfuploadify.queueData.uploadQueue = []; swfuploadify.stopUpload(); }); }, // Start uploading files in the queue upload : function() { var args = arguments; this.each(function() { // Create a reference to the jQuery DOM object var $this = $(this), swfuploadify = $this.data('uploadify'); // Reset the queue information swfuploadify.queueData.averageSpeed = 0; swfuploadify.queueData.uploadSize = 0; swfuploadify.queueData.bytesUploaded = 0; swfuploadify.queueData.uploadQueue = []; // Upload the files if (args[0]) { if (args[0] == '*') { swfuploadify.queueData.uploadSize = swfuploadify.queueData.queueSize; swfuploadify.queueData.uploadQueue.push('*'); swfuploadify.startUpload(); } else { for (var n = 0; n < args.length; n++) { swfuploadify.queueData.uploadSize += swfuploadify.queueData.files[args[n]].size; swfuploadify.queueData.uploadQueue.push(args[n]); } swfuploadify.startUpload(swfuploadify.queueData.uploadQueue.shift()); } } else { swfuploadify.startUpload(); } }); } } // These functions handle all the events that occur with the file uploader var handlers = { // Triggered when the file dialog is opened onDialogOpen : function() { // Load the swfupload settings var settings = this.settings; // Reset some queue info this.queueData.errorMsg = 'Some files were not added to the queue:'; this.queueData.filesReplaced = 0; this.queueData.filesCancelled = 0; // Call the user-defined event handler if (settings.onDialogOpen) settings.onDialogOpen.call(this); }, // Triggered when the browse dialog is closed 当浏览对话框关闭时引发 onDialogClose : function(filesSelected, filesQueued, queueLength) { // Load the swfupload settings var settings = this.settings; // Update the queue information 更新队列信息 this.queueData.filesErrored = filesSelected - filesQueued; this.queueData.filesSelected = filesSelected; this.queueData.filesQueued = filesQueued - this.queueData.filesCancelled; this.queueData.queueLength = queueLength; // Run the default event handler 运行默认事件处理程序 if ($.inArray('onDialogClose', settings.overrideEvents) < 0) { if (this.queueData.filesErrored > 0) { alert(this.queueData.errorMsg); } } // Call the user-defined event handler 调用自定义事件处理程序 if (settings.onDialogClose) settings.onDialogClose.call(this, this.queueData); // Upload the files if auto is true 上传文件,如果汽车是真实的 if (settings.auto) $('#' + settings.id).uploadify('upload', '*'); }, // Triggered once for each file added to the queue 为每个文件添加到队列触发一次 onSelect : function(file) { // Load the swfupload settings var settings = this.settings; // Check if a file with the same name exists in the queue 检查队列中是否存在同名的文件 var queuedFile = {}; for (var n in this.queueData.files) { queuedFile = this.queueData.files[n]; if (queuedFile.uploaded != true && queuedFile.name == file.name) { var replaceQueueItem = confirm('The file named "' + file.name + '" is already in the queue.\nDo you want to replace the existing item in the queue?'); if (!replaceQueueItem) { this.cancelUpload(file.id); this.queueData.filesCancelled++; return false; } else { $('#' + queuedFile.id).remove(); this.cancelUpload(queuedFile.id); this.queueData.filesReplaced++; } } } // Get the size of the file 获取文件的大小 var fileSize = Math.round(file.size / 1024); var suffix = 'KB'; if (fileSize > 1000) { fileSize = Math.round(fileSize / 1000); suffix = 'MB'; } var fileSizeParts = fileSize.toString().split('.'); fileSize = fileSizeParts[0]; if (fileSizeParts.length > 1) { fileSize += '.' + fileSizeParts[1].substr(0,2); } fileSize += suffix; // Truncate the filename if it's too long 截断文件名,如果它太长 var fileName = file.name; if (fileName.length > 25) { fileName = fileName.substr(0,25) + '...'; } // Create the file data object 创建文件数据对象 itemData = { 'fileID' : file.id, 'instanceID' : settings.id, 'fileName' : fileName, 'fileSize' : fileSize } // Create the file item template 创建文件项模板 if (settings.itemTemplate == false) { settings.itemTemplate = '<div id="${fileID}" class="uploadify-queue-item">\ <div class="cancel">\ <a href="javascript:$(\'#${instanceID}\').uploadify(\'cancel\', \'${fileID}\')">X</a>\ </div>\ <span class="fileName">${fileName} (${fileSize})</span><span class="data"></span>\ <div class="uploadify-progress">\ <div class="uploadify-progress-bar"><!--Progress Bar--></div>\ </div>\ </div>'; } // Run the default event handler 运行默认事件处理程序 if ($.inArray('onSelect', settings.overrideEvents) < 0) { // Replace the item data in the template 替换模板中的项目数据 itemHTML = settings.itemTemplate; for (var d in itemData) { itemHTML = itemHTML.replace(new RegExp('\\$\\{' + d + '\\}', 'g'), itemData[d]); } // Add the file item to the queue 将文件项添加到队列中 $('#' + settings.queueID).append(itemHTML); } this.queueData.queueSize += file.size; this.queueData.files[file.id] = file; // Call the user-defined event handler 调用自定义事件处理程序 if (settings.onSelect) settings.onSelect.apply(this, arguments); }, // Triggered when a file is not added to the queue 当文件未添加到队列时引发 onSelectError : function(file, errorCode, errorMsg) { // Load the swfupload settings 负荷swfupload设置 var settings = this.settings; // Run the default event handler 运行默认事件处理程序 if ($.inArray('onSelectError', settings.overrideEvents) < 0) { switch(errorCode) { case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: if (settings.queueSizeLimit > errorMsg) { this.queueData.errorMsg += '\nThe number of files selected exceeds the remaining upload limit (' + errorMsg + ').'; } else { this.queueData.errorMsg += '\nThe number of files selected exceeds the queue size limit (' + settings.queueSizeLimit + ').'; } break; case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: this.queueData.errorMsg += '\nThe file "' + file.name + '" exceeds the size limit (' + settings.fileSizeLimit + ').'; break; case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: this.queueData.errorMsg += '\nThe file "' + file.name + '" is empty.'; break; case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: this.queueData.errorMsg += '\nThe file "' + file.name + '" is not an accepted file type (' + settings.fileTypeDesc + ').'; break; } } if (errorCode != SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) { delete this.queueData.files[file.id]; } // Call the user-defined event handler 调用自定义事件处理程序 if (settings.onSelectError) settings.onSelectError.apply(this, arguments); }, // Triggered when all the files in the queue have been processed 当队列中的所有文件已被处理时触发 onQueueComplete : function() { if (this.settings.onQueueComplete) this.settings.onQueueComplete.call(this, this.settings.queueData); }, // Triggered when a file upload successfully completes 当文件上载成功完成时引发 onUploadComplete : function(file) { // Load the swfupload settings var settings = this.settings, swfuploadify = this; // Check if all the files have completed uploading var stats = this.getStats(); this.queueData.queueLength = stats.files_queued; if (this.queueData.uploadQueue[0] == '*') { if (this.queueData.queueLength > 0) { this.startUpload(); } else { this.queueData.uploadQueue = []; // Call the user-defined event handler for queue complete if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData); } } else { if (this.queueData.uploadQueue.length > 0) { this.startUpload(this.queueData.uploadQueue.shift()); } else { this.queueData.uploadQueue = []; // Call the user-defined event handler for queue complete if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData); } } // Call the default event handler if ($.inArray('onUploadComplete', settings.overrideEvents) < 0) { if (settings.removeCompleted) { switch (file.filestatus) { case SWFUpload.FILE_STATUS.COMPLETE: setTimeout(function() { if ($('#' + file.id)) { swfuploadify.queueData.queueSize -= file.size; swfuploadify.queueData.queueLength -= 1; delete swfuploadify.queueData.files[file.id] $('#' + file.id).fadeOut(500, function() { $(this).remove(); }); } }, settings.removeTimeout * 1000); break; case SWFUpload.FILE_STATUS.ERROR: if (!settings.requeueErrors) { setTimeout(function() { if ($('#' + file.id)) { swfuploadify.queueData.queueSize -= file.size; swfuploadify.queueData.queueLength -= 1; delete swfuploadify.queueData.files[file.id]; $('#' + file.id).fadeOut(500, function() { $(this).remove(); }); } }, settings.removeTimeout * 1000); } break; } } else { file.uploaded = true; } } // Call the user-defined event handler if (settings.onUploadComplete) settings.onUploadComplete.call(this, file); }, // Triggered when a file upload returns an error 当文件上载返回错误时引发 onUploadError : function(file, errorCode, errorMsg) { // Load the swfupload settings var settings = this.settings; // Set the error string var errorString = 'Error'; switch(errorCode) { case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: errorString = 'HTTP Error (' + errorMsg + ')'; break; case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL: errorString = 'Missing Upload URL'; break; case SWFUpload.UPLOAD_ERROR.IO_ERROR: errorString = 'IO Error'; break; case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: errorString = 'Security Error'; break; case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED://上传的文件数量超过了允许的最大值 //alert('The upload limit has been reached (' + errorMsg + ').'); errorString = 'Exceeds Upload Limit'; break; case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: errorString = 'Failed'; break; case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND: break; case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: errorString = 'Validation Error'; break; case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: errorString = 'Cancelled'; this.queueData.queueSize -= file.size; this.queueData.queueLength -= 1; if (file.status == SWFUpload.FILE_STATUS.IN_PROGRESS || $.inArray(file.id, this.queueData.uploadQueue) >= 0) { this.queueData.uploadSize -= file.size; } // Trigger the onCancel event if (settings.onCancel) settings.onCancel.call(this, file); delete this.queueData.files[file.id]; break; case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: errorString = 'Stopped'; break; } // Call the default event handler if ($.inArray('onUploadError', settings.overrideEvents) < 0) { //上传被取消了或上传被终止了 if (errorCode != SWFUpload.UPLOAD_ERROR.FILE_CANCELLED && errorCode != SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED) { $('#' + file.id).addClass('uploadify-error'); } // Reset the progress bar 重置进度条 $('#' + file.id).find('.uploadify-progress-bar').css('width','1px'); // Add the error message to the queue item 将错误消息添加到队列项 if (errorCode != SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND && file.status != SWFUpload.FILE_STATUS.COMPLETE) { $('#' + file.id).find('.data').html(' - ' + errorString); } } var stats = this.getStats(); this.queueData.uploadsErrored = stats.upload_errors; // Call the user-defined event handler if (settings.onUploadError) settings.onUploadError.call(this, file, errorCode, errorMsg, errorString); }, // Triggered periodically during a file upload onUploadProgress : function(file, fileBytesLoaded, fileTotalBytes) { // Load the swfupload settings var settings = this.settings; // Setup all the variables var timer = new Date(); var newTime = timer.getTime(); var lapsedTime = newTime - this.timer; if (lapsedTime > 500) { this.timer = newTime; } var lapsedBytes = fileBytesLoaded - this.bytesLoaded; this.bytesLoaded = fileBytesLoaded; var queueBytesLoaded = this.queueData.queueBytesUploaded + fileBytesLoaded; var percentage = Math.round(fileBytesLoaded / fileTotalBytes * 100); // Calculate the average speed var suffix = 'KB/s'; var mbs = 0; var kbs = (lapsedBytes / 1024) / (lapsedTime / 1000); kbs = Math.floor(kbs * 10) / 10; if (this.queueData.averageSpeed > 0) { this.queueData.averageSpeed = Math.floor((this.queueData.averageSpeed + kbs) / 2); } else { this.queueData.averageSpeed = Math.floor(kbs); } if (kbs > 1000) { mbs = (kbs * .001); this.queueData.averageSpeed = Math.floor(mbs); suffix = 'MB/s'; } // Call the default event handler if ($.inArray('onUploadProgress', settings.overrideEvents) < 0) { if (settings.progressData == 'percentage') { $('#' + file.id).find('.data').html(' - ' + percentage + '%'); } else if (settings.progressData == 'speed' && lapsedTime > 500) { $('#' + file.id).find('.data').html(' - ' + this.queueData.averageSpeed + suffix); } $('#' + file.id).find('.uploadify-progress-bar').css('width', percentage + '%'); } // Call the user-defined event handler if (settings.onUploadProgress) settings.onUploadProgress.call(this, file, fileBytesLoaded, fileTotalBytes, queueBytesLoaded, this.queueData.uploadSize); }, // Triggered right before a file is uploaded 在文件上传前触发 onUploadStart : function(file) { // Load the swfupload settings var settings = this.settings; var timer = new Date(); this.timer = timer.getTime(); this.bytesLoaded = 0; if (this.queueData.uploadQueue.length == 0) { this.queueData.uploadSize = file.size; } if (settings.checkExisting) { $.ajax({ type : 'POST', async : false, url : settings.checkExisting, data : {filename: file.name}, success : function(data) { if (data == 1) { var overwrite = confirm('A file with the name "' + file.name + '" already exists on the server.\nWould you like to replace the existing file?'); if (!overwrite) { this.cancelUpload(file.id); $('#' + file.id).remove(); if (this.queueData.uploadQueue.length > 0 && this.queueData.queueLength > 0) { if (this.queueData.uploadQueue[0] == '*') { this.startUpload(); } else { this.startUpload(this.queueData.uploadQueue.shift()); } } } } } }); } // Call the user-defined event handler 调用自定义事件处理程序 if (settings.onUploadStart) settings.onUploadStart.call(this, file); }, // Triggered when a file upload returns a successful code onUploadSuccess : function(file, data, response) { // Load the swfupload settings var settings = this.settings; var stats = this.getStats(); this.queueData.uploadsSuccessful = stats.successful_uploads; this.queueData.queueBytesUploaded += file.size; // Call the default event handler if ($.inArray('onUploadSuccess', settings.overrideEvents) < 0) { $('#' + file.id).find('.data').html(' - Complete'); } // Call the user-defined event handler 调用自定义事件处理程序 if (settings.onUploadSuccess) settings.onUploadSuccess.call(this, file, data, response); } } $.fn.uploadify = function(method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('The method ' + method + ' does not exist in $.uploadify'); } } })($);