Uploadify是一个基于JQuery的文件上传控件,支持ajax无刷新上传,比较好用,现在用着一个不爽的地方是——每个版本的属性名和事件名、方法名都有一些不一样,这在遇到问题,查资料的时候会比较麻烦,这篇博客所说明的是3.2.1版本。
- 官方网站:http://www.uploadify.com/
- 官方文档:http://www.uploadify.com/documentation/
- 官方下载:http://www.uploadify.com/wp-content/uploads/files/uploadify.zip
名称 | 类型 | 默认值 | 说明 |
auto | Boolean | true | 当设置为false时,文件在被添加到队列时,不会自动上传;手动上传需要使用upload方法 |
buttonClass | String | Empty String | 上传按钮的样式属性名(ClassName),该属性必须填写 |
buttonCursor | Syting | 'hand' | 当鼠标移动到浏览按钮上时,光变的样式,这个属性有两个可选值:'hand’, 'arrow' |
buttonImage | String | null | 浏览按钮的背景图片的路径,这只是一个简便方式,最好的方式是通过CSS来设置 |
buttonText | String | 'SELECT FILES' | 浏览按钮里的文本,可以包含html |
checkExisting | String | false | 目标文件夹的路径,检查现在上传的文件是否已存在于目标文件夹(以名称辨别),存在返回1,不存在返回0 |
debug | Boolean | false | 设置为true, 则开启了调试模式 |
fileObjName | String | 'Filedata' | 文件名称对象, 用于在服务器端获取文件。例如,把该属性设置为'the_files',那么在PHP中,可以使用$_FILES['the_files'];来获取文件 |
fileSizeLimit | Number,String | 设置最大上传限量,可以使用数字或字符串,字符串是包含单位(B, KB, MB, GB)的字符串, 使用数字, 则默认为KB | |
fileTypeDesc | String | 'All Files' | 文件类型说明(如果没错的话,说的应该是类似图中的All Files说明,![]() |
fileTypeExts | String | '*.*' | 允许上传的文件类型,可以设置多种类型('*.doc; *.docx'),官方文档说可以使用手动键入文件名(包含后缀)的方式来绕过这个设置,建议在服务器断对文件类型再次进行判断。不过我试着,手动键入非法文件,结果提示添加失败,同样不知道是不是系统的问题。 |
formData | JSON Object | Empty Object | 上传文件时附带的数据, 直接在此处添加数据,只能添加静态数据, 如果想添加动态数据, 需要使用onUploadStart事件,详见demo |
height | Number | 30 | 设置浏览按钮的高度,单位像素(px) |
itemTemplate | String | false | 上传的文件列表模版,模版提供了四个可选标签,instanceID:Uploadify的实例ID;fileID:队列中文件的ID;fileName:文件名称;fileSize:文件的大小;使用方法:${fileID} |
method | String | 'post' | 提交文件的方式是以post还是get |
multi | Boolean | true | 是否允许一次选择多个文件,设置为false,则每次只能选择一个文件,但是可以通多次选择来选择多个 |
overrideEvents | JSON Array | Empty Array | 设置Uploadify里的哪些事件可以被用户重写。'overrideEvents' :{'onCancel', 'onInit'}表示'onCancel'事件和'onInit'事件可以被用户重写 |
preventCaching | Boolean | true | 设置为true,防止swf文件缓存,,防止缓存的方式是在swf的URL后面添加一个随机参数 |
progressData | String | 'percentage' | 在上传文件时,是显示上传速度,还是显示已上传的百分比,该属性有两个可选值:'percentage', 'speed' |
queueID | String | false | 用指定DOM元素显示文件上传队列,该属性为指定DOM的ID |
queueSizeLimit | Number | 999 | 同一时间上传队列允许的最大文件数,当选定添加到队列的文件数超过指定大小,将会触发onSelectError事件 |
removeCompleted | Boolean | true | 默认在文件上传完成后,将其从队列中移除,设置为false后, 将在队列中保留上传完成的文件 |
removeTimeout | Number | 3 | 当removeCompleted设置为true时,该属性设置 在文件上传完毕后,经过多少秒后从队列中移除 |
requeueErrors | Boolean | false | 设置为true时,将对上传产生错误的文件重新添加到队列中,并在此尝试上传 |
successTimeout | Number | 30 | 上传完成后,等待服务器响应的时间,默认30秒,当超过这个时间,那么将认为该文件上传成功 |
swf | String | ‘uploadify.swf’ | swf的路径,该属性必须填写 |
uploader | String | 'uploadify.php' | 服务端脚本文件路径 , 该属性必须填写 |
uploadLimit | Number | 999 | 文件上传量限制。这个与queueSizeLimit不同,后者是队列中同一时间最多允许有多少个文件,前者是文件总上传量。当超过限定值是会触发onUploadError事件 |
width | Number | 120 | 浏览按钮的宽度,单位像素(px) |
名称 | 说明 |
onCancel | 取消队列中上传的文件时触发,该事件获取一个参数file,该参数包含被取消的文件的信息 |
onClearQueue | 当执行cancel方法,且方法参数为'*'时触发该事件, 该事件获取一个参数queueItemCount,该参数为被取消的文件的个数 |
onDestroy | 当使用destroy方法时触发 |
onDialogClose | 关闭文件浏览窗口时触发,该事件获取一个参数queueData,该参数有五个属性:filesSelected:浏览窗口中选中的文件数;filesQueued:添加到队列中的文件数;filesReplaced:被替换的文件个数;filesCancelled:被取消上传到队列的文件数;filesErrored:上传到队列时出错的文件数。该事件可以被重写 |
onDialogOpen | 打开文件浏览窗口时触发,该事件里的代码可能会在文件浏览窗口关闭时才执行 |
onDisable | 禁用Uploadify时触发,通过disable方法来禁用Uploadify |
onEnable | 启用Uploadify时触发,通过disable方法来启用Uploadify |
onFallback | 在初始化时,若检测不到浏览器有兼容性的flash版本时触发 |
onInit | 在Uploadify初始化时触发,该事件获取一个参数instance,该参数为Uploadify的一个实例 |
onQueueComplete | 队列中的文件上传完毕后触发,该事件获取一个参数queueData,该参数有两个属性:uploadsSuccessful:成功上传的文件数量;uploadsErrored:上传失败的文件数量 |
onSelect | 文件在文件浏览窗口被选择并被添加到文件队列时触发,该事件获取一个参数file,该参数为被添加的文件的一个实例,该事件可以被重写 |
onSelectError | 当被选择文件在添加到文件队列出错时触发,该事件获取三个参数file、errorCode、errorMsg,file:发生错误的文件对象实例;errorCode:错误码,用以确定错误的类型,内容可能包含三个常量(QUEUE_LIMIT_EXCEEDED:选择的文件数量超过限定值;FILE_EXCEEDS_SIZE_LIMIT:文件大小超过限定值;ZERO_BYTE_FILE:文件没有大小;INVALID_FILETYPE:文件类型不是规定的类型) |
onSWFReady | 在flash文件加载成功并准备好后触发 |
onUploadComplete | 队列中每个文件上传完毕后触发,该事件获取一个参数file,该参数为上传完毕的文件的实例,如果想知道上传完毕的文件具体是上传成功哈市上传失败,建议使用onUploadSuccess和onUploadError事件。事件可重写 |
onUploadError | 上传某个文件出错时触发,该事件获取四个参数:file:出错文件对象的实例;errorCode:错误码,是否与onSelectError的errorCode相同,未知;errorMsg:错误信息;errorString:错误相信信息 |
onUploadProgress | 每更新一个文件的上传进度的时候触发,该事件获取五个参数:file:更新进度的文件实例;bytesUploaded:文件相对上一次触发事件,更新了多少字节;bytesTotal:被更新进度的文件的总字节数;totalBytesUploaded:被更新进度的文件,已经上传的总字节数;totalBytesTotal:所有文件总共上传的字节数。该事件可以被重写 |
onUploadStart | 每个文件开始上传时触发,该事件1获取一个参数file:开始上传的文件实例 |
onUploadSuccess | 每个文件上传成功时触发,该事件获取三个参数:file:上传成功的文件对象实例;data:服务器返回的数据;response:来自服务器的响应,true表示成功,false表示服务器无响应,当超过successTimeout设定的时间,则默认返回true |
名称 | 说明 |
cancel | 取消上传,可传参数,以指定需要取消上传的文件。当无参数时,默认移除第一个;当参数为'*'时,则移除队列中所有文件;参数可为queueID,其实际效果与'*'相同。移除所有;参数可为itemTemplate属性中的fileID,表示移除指定fileID的文件,参数可传多个,表示同时移除多个,在3.2.1版本中,fileID默认为SWFUpload_0_X,X对应上传队列中的顺序。当上传队列文件过多时,又希望取消第几个或第a-b个文件时,官方的传参方式会显得非常麻烦,我个人修改了一下源文件,有兴趣的可以看一下 |
destroy | 取消uploadify上传文件方式, 改用html默认的file |
display | 通过该方法启动或禁用Uploadify,禁用方式是启用或禁用浏览按钮,该方法接收一个Boolean参数,true禁用,false启用 |
setting | 返回或更新Uploadify实例的值,该方法接收三个参数:name:这里一般都是填的settings,因为是用$('#file_upload').uploadify('settings', '', '');的方式调用setting方法的;value:希望被设置或返回值的对象名称,当方法没有第三个参数的时候表示返回value对象的值;resetObjects:当使用第三个参数时,则方法为设置value对象的值为resetObjects |
stop | 停止当前上传,并重置上传进度 |
upload | 开始上传队列中的文件,该方法接收一个参数fileID,这里的fileID与cancel方法里的fileID意义相同,关于类似cancel方法的扩展的upload方法扩展,因为代码类似,所以再此就不再展示出来了 |
formData传递静态与动态数据
使用如下方式,只能传递静态数据,不能传递动态数据:
$(function() { $("#file_upload").uploadify({ 'formData' : {'someKey' : 'someValue', 'someOtherKey' : 1}, 'swf' : '/uploadify/uploadify.swf', 'uploader' : '/uploadify/uploadify.php', }); });
formData包含两个键值对, 因为值时固定的, 所以是静态数据,而类似获取文本框的输入值来作为传递数据,此为动态数据,动态数据用此方法传递会不能传送后输入的数据,而只能传递数据初始值。
例如有一文本框<input type="text" id="txtName" value="UNKONW"/>,用如下方式传递数据,当在文本框输入其他数据后,最终服务器获取到的值时"UNKNOW"。
$(function() { $("#file_upload").uploadify({ 'formData' : {'name':$("#txtName").val()}, 'swf' : '/uploadify/uploadify.swf', 'uploader' : '/uploadify/uploadify.php' }); });
解决方法:在onUploadStart方法中设置动态数据的值
$(function() { $("#file_upload").uploadify({ 'swf' : '/uploadify/uploadify.swf', 'uploader' : '/uploadify/uploadify.php', 'onUploadStart' : function(file) { $("#file_upload").uploadify("settings", “formData", {"name", $("#txtName").val()}); } }); });
可能大家有看到过使用uploadifySettings来完成动态数据传输,不过3.2版本的Uploadify并没有定义这个方法, 这个应该是3.0版本之前的方法吧。
官方的cancel参数,只有在取消队列中第一个文件和取消所有文件时比较方便,但是我们在上传很多文件时, 出于某种原因, 想要取消第X个和第Y、第...个文件或直接想取消第X到第Y个文件的上传死,官方的方法就显得比较无力。
类似uploadify这种资源都是开源的, 我们可以直接修改其源码,以方便自己, 而且修改的时候, 自己并不一定需要知道这些代码的具体意思,只要知道大概的, 就能修改的自己可以用了, 下面是我实现上面两种想法的代码, /*===*/到/*===*/之间的的代码是我添加上去的。
这里的思路非常简单,就是添加了参数的两种情况,需要移除第X个和第Y个的时候,使用这样的语句:$('#file_upload').uploadify('cancel', x, y); 这里要求x、y都是数字,大小顺序无关紧要;需要移除第x到第y个的时候,$('#file_upload').uploadify('cancel', x, '-', y);这里要求x、y都是数字,且x>y。
cancel : function(fileID, supressEvent) { var args = arguments; this.each(function () { debugger; // 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 if (args[1] != null && args[1] == '-' && args[0] < args[2] && args[2] < $('#' + settings.queueID).find('.uploadify-queue-item').length) { for (var n = args[0]; n <= args[2]; n++) { var item = $('#' + settings.queueID).find('.uploadify-queue-item').get(n - 1); $item = $(item); swfuploadify.cancelUpload($item.attr('id')); $item.find('.data').removeClass('data').html(' - Cancelled'); $item.find('.uploadify-progress-bar').remove(); $item.delay(1).fadeOut(5, function () { $(this).remove(); }); } } else if (!isNaN(args[0])) { for (var n = 0; n < args.length; n++) { var item = $('#' + settings.queueID).find('.uploadify-queue-item').get(args[n] - 1); $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(); }); } } /*====================================================================================================*/ else { for (var n = 0; n < args.length; n++) { swfuploadify.cancelUpload(args[n]); $('#' + 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(); }); } }); },
下面是我的一个疑问,表述的比较混乱,如果哪位大哥能看懂,并知道原因,还请不吝告知
这个代码比我开始写的代码要简单一些, 开始的时候, 对于移除x到y的所有文件的操作,因为是循环遍历所有文件,然后一个一个的移除第某个,利用remove(index)。比如移除第2个到第5个的所有文件,第一次遍历获取了第2个文件,并移除,那么第3个就变成了第2个,依次类推, 这样就不能是第一次移除第2个,第2次移除第三个,而是直接移除第2个(5-2+1)次。而对于另一种情况——移除指定顺序ID的文件时,因为允许传递过来的ID是乱序, 所以会比较麻烦, 需要先将传递过来的ID进行一个升序排序, 然后再对每个ID减去他们数组索引(第一个减0,第二个减1...), 因为每次移除一个, 后面的文件顺序就要减1。 而事实并没有我一开始做的那么复杂,这里的remove,是在循环完成后一起remove的,这里调用的应该是jquery标准的remove,但是我试了下用一个简单的例子试了下remove,结果是 执行完remove语句后,指定的元素就被移除了, 为什么uploadify这里的remove却是等在循环完后一起remove的, 有点想不通。