uploadify多文件上传

咱们都知道,通常上传文件的实现都是一个一个上传文件实现的,或者经过多添加几个按钮。有没有批量上传呢?确定是有的,那就是Jquery插件uploadify。Uploadify是JQuery的一个上传插件,实现的效果很是不错,带进度显示。官方提供的实例是php版本的,本文将详细介绍Uploadify插件的运用。javascript

首先是我本身使用的简易的js处理文件php

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文件(自定义写的)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文件,主要是上传文件之后的显示样式html

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

样式图java

已上传样式图jquery

 

给你们看看我给jquery.uploadify.js添加的注释说明ajax

(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');
        }

    }

})($);