问题

在使用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不为空

jquery ajaxFileUpload 只有第一次管用_ajax

提交旧元素,保留新元素,新元素保留旧元素的绑定事件

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()">

总结

没事还是应该多研究源码,虽然费时间,但确确实实长见识。