问题

在使用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()">

总结

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


发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

js 整数、手机号正则表达式详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。