问题
在使用jquery ajaxfileupload插件时,发现只有第一次上传好使,第二次及以后,都不管用了。
大体代码如下
<style type="text/javascript" src="jquery.js">
<style type="text/javascript" src="ajaxfileupload.js">
<input type="file" id="myfile" >
<script type="text/javascript">
$(function(){
$("#myfile").change(function(e){
$.ajaxFileUpload({
fileElementId:"myfile",
success:function(data,status){
}
});
});
});
</script>
分析
研究得知ajaxFileupload插件上传文件的原理是,创建隐藏form、iframe,将form的target设置为iframe,clonefile元素,将旧元素移动到隐藏form中,将新元素newElement放在旧元素的前边。上传完后,删除隐藏的form和iframe,这样就能实现无刷新上传文件的效果。
因为旧元素随着form被删除而删除,而新元素没有绑定之前的hange事件,所以,上传一次后,不再出发change时间,从而就出现不好使的问题。
尝试修复
提交新元素,保留旧元素
既然知道原理了,那么自然想到,不提交旧元素,提交旧元素就是了。找到源码
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
改为
var newElement = jQuery(oldElement).clone();
jQuery(newElement ).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(newElement ).appendTo(form);
一提交,发现表单中的file为空!用的是chrome浏览器,第一反应浏览器的问题,换为firefox后,提交,没问题!一番搜索后明白了,涉及到安全策略问题,浏览器一般是不允许clone file的。
chrome中debug时,发现
jQuery(newElement ).val();//这个值是空,应该跟安全策略有关系,所以file为空
jQuery(oldElement).val();//有值,所以file不为空
提交旧元素,保留新元素,新元素保留旧元素的绑定事件
ok,这条路走不通了,那就走更外一条路吧,就是clone新元素的时候,将绑定事件也clone出来,查找api,发现clone(cloneEventFlag),正好参数可以接收是否clone事件,源码
var newElement = jQuery(oldElement).clone();
改为
var newElement = jQuery(oldElement).clone(true);
还是不行!,这次我不知道原因了。
将onchange设置到标签上
解决方案简单又直接,就是将onchange设置到标签上,而不再使用jquery绑定change事件的方式。
<input type="file" onchange="uploadFile()">
总结
没事还是应该多研究源码,虽然费时间,但确确实实长见识。