swfupload 2.2 文件最大上传个数的重编译

时间:2022-08-30 10:10:09

项目中用到了swfupload 2.2 ,并且有一个需求,就是在上传个数限定的条件下上传文件后可以有一个删除操作,由此我们遇到了问题 ,虽然 file_upload_limit 参数可以控制文件上传总数,但是js在执行删除时,flash内部的参数没有更改,file_upload_limit代表的是文件成功的个数,而不是我 们想要的(如果我的问题你还没有明白,比如 我们将file_upload_limit 设为5 ,我们现在成功上传3张,用js 删除其中2张,那么我们现在html中还有一张图片,我们还可以上传2张图片,而不是4张,而我们想要的结果是用户最大可以上传5张,现在用户可能一张也 保存不了)。 swfupload 内部的文件个数统计是由flash完成的,我翻看了swfupload.js(我看的是2.5版,并做了些注释,文章下方提供下载),证实js对此无能为力。为此我这个as 初学者不得不对swfload.swf进行一点修改。多亏swfupload是开源的,我们可以在google code 下载到 源码,源码中没有提供fla文件,我使用SWFDecompiler 对 2.5版进行反编译的时候发现SWFDecompiler 5.6和5.5 在还没有完成的时候就会崩溃掉,而swfupload 2.2则没有这种问题。而项目中用到的正是2.2 ,不用我操心了。

2.2版中的fla文件没有什么稀奇,就是一个300 px * 300 px(右击画布在 “文档属性”中设置 ) 的新建文件引入了 swfupload.as (看来反编译都是白费劲了).

swfupload 2.2 文件最大上传个数的重编译引入swfupload.as

为了添加删除操作我们要对handlers.js (位于 swfupload demo版applicationdemo 文件夹 )做一点修改 ,我们使用了jQuery 对addImage 函数进行了修改。

function addImage(src,touxiang) { 	var newImg = document.createElement("img"); 	newImg.style.margin = "5px"; 	var $licon=$('<li><p class="p_box"><span><a href="#">删除</a></span><input type="radio">默认显示</p><p><input type="text" name=""></p></li>') 	$licon.prepend($(newImg)); 	document.getElementById("thumbnails").appendChild($licon.get(0)); 	if (newImg.filters) { 		try { 			newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0; 		} catch (e) { 			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet. 			newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')'; 		} 	} else { 		newImg.style.opacity = 0; 	}  	newImg.onload = function () { 		fadeIn(newImg, 0); 	}; 	newImg.src = src; } 
swfupload 2.2 文件最大上传个数的重编译现在上传的图片

这是文档结构的,我们还要添加删除操作。

		$('.p_box ').live('click',function(e){ 				$(this).parents('li').remove(); 				e.preventDefault(); 		}); 

那么剩下的就是as的事了,如何使用js 控制flash文件上传个数那?

在swfupload.js中我看到了 callFlash 方法:

SWFUpload.prototype.callFlash = function (functionName, argumentArray) { 	argumentArray = argumentArray || [];  	var movieElement = this.getMovieElement(); 	var returnValue, returnString;  	// Flash's method if calling ExternalInterface methods (code adapted from MooTools). 	try { 		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>'); 		returnValue = eval(returnString); 	} catch (ex) { 		throw "Call to " + functionName + " failed"; 	}  	// Unescape file post param values 	if (returnValue != undefined &amp;amp;&amp;amp; typeof returnValue.post === "object") { 		returnValue = this.unescapeFilePostParams(returnValue); 	}  	return returnValue; }; 

它使用了如下的方法向flash中传递参数。

movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>'); 

具体的原理也不知道,CallFunction和invoke 的介绍网上好像不是太多。
知道了如何传递参数那么我们就可以仿照着写一个函数,我们称为minusNum

SWFUpload.prototype.minusNum = function () { 	 this.callFlash("minusNum"); }; 

swfupload.as 和swfupload.js中定义的函数基本是一一对于的, 这个函数的意思就是要要flash执行minusNum方法。
下面该干什么那,当然是寻找as中控制上传个数的参数并进行修改了。在尝试了,remaining_uploads和 queue_slots_remaining 后终于找到了真的的参数 successful_uploads 。由于他已经是全局变量,不需要我们修改了,我们要做的是添加方法,在每次js删除操作时减小它的值。
在SetupExternalInterface 中添加

	ExternalInterface.addCallback("minusNum", this.minusNum); 

在合适的地方添加方法

private function minusNum():void{ 			if(this.successful_uploads>0){ 				this.successful_uploads--; 			} 		} 

好的这样只要我们每次删除时执行一次minusNum方法就可以了,假设我们实例化swfupload为swfu,上方删除操作的代码可以改为:

		$('.p_box a').live('click',function(e){ 				$(this).parents('li').remove(); 				swfu.minusNum() 				e.preventDefault(); 		});