我们在一个包括很多文本框和上传图片的表单中,为了更好的用户体验需要把点击上传后的图片在提交表单中显示出来,有以下几个方案:
1. 点击上传后获得图片的本地路径,之后显示在网页上,这种方式行不通,因为很多浏览器为了安全性无法获得本地路径。
2. 先把图片异步上传到服务器然后利用回调函数回显图片,由于ajax是不支持带有图片上传的表单提交的,所以我们需要用一些插件,我们的选择有jquery.form.js和ajaxfileupload.js并且请使用jquery-1.4.2-min.js以下版本,或者在高版本中加入
handleError: function( s, xhr, status, e ) {
// If a local callback was specified, fire it
if ( s.error ) {
s.error.call( s.context || s, xhr, status, e );
}
// Fire the global callback
if ( s.global ) {
(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
}
},
然而jquery.form.js可以实现上传,但依然无法执行success的回调存在一些BUG
3. 使用ajaxfileupload.js实现
Html:
<img height="100"width="100" src="img/update_pic.png">
<span style="visibility: hidden">重新上传</span>
<form action="/Struts2Upload/test/upload.action" method="post"enctype="multipart/form-data" id="upfrom">
<input type="file" id="btn_file" name="btn_file"style="display:none" οnchange="uploadImage();">
<input type="button" name="btn_abc" value="浏览" οnclick="F_Open_dialog()">
</form>
JavaScript:
<script type="text/javascript" src="js/jquery-1.4.2-min.js"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>
<script type="text/javascript">
function F_Open_dialog(){
document.getElementById('btn_file').click();
}
function uploadImage() {
$.ajaxFileUpload({
url: "/Struts2Upload/test/uploadAjax.action",
secureuri:false,
fileElementId:"btn_file",
dataType: "text",
beforeSend: function(){
$('img').attr('src','img/vote_img_loading.png');
},
error: function(data, status, e) {
alert(e);
},
success: function(data, textStatus){
var dataAddr =data.substring(5,data.length-6);
dataAddr = eval("(" +dataAddr + ")");
$('img').attr('src',dataAddr.imPath);
}
});
}
</script>
代码写成这样我们又会发现一些问题dataType返回类型如果是json类型的话,
(1). FF,Chrome会报SynxError这是因为ajaxfileupload.js缺少一段处理
uploadHttpData:function( r, type ) {
vardata = !type;
data= type == "xml" || data ? r.responseXML : r.responseText;
//If the type is "script", eval it in global context
if( type == "script" )
jQuery.globalEval(data );
//Get the JavaScript object, if JSON is used.
if( type == "json" ){
以下为新增代码///
data= r.responseText;
varstart = data.indexOf(">");
if(start!= -1) {
varend = data.indexOf("<", start + 1);
if(end!= -1) {
data= data.substring(start + 1, end);
}
}
///以上为新增代码///
eval( "data = " + data );
}
//evaluate scripts within html
if( type == "html" )
jQuery("<div>").html(data).evalScripts();
return data;
}
(2). IE无法执行Ajax请求
这是因为我们使用了button去调用file的原因,IE认为只有用户亲自去点击file才执行form的提交,因此我们需要修改一下代码,原理如下:
让file盖在A标签上面,file设置透明,用户看到A的外观,点击的是file
4. 修改后的ajaxfileupload.js实现
Html:
<img height="100"width="100" src="img/update_pic.png">
<span style="visibility: hidden">重新上传</span>
<a style="position:relative;display:block;width:100px;height:30px;
background:#EEE;border:0pxsolid #999;text-align:center;" href="javascript:void(0);">
浏览
<form action="/Struts2Upload/test/upload.action" method="post"enctype="multipart/form-data" id="upfrom">
<input type="file" id="btn_file" name="btn_file"οnchange="uploadImage();"
style="position:absolute;left:0;top:0;width:100px;height:100%;z-index:999;opacity:0;filter:alpha(opacity=0)">
</form>
</a>
JavaScript:
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>
<script type="text/javascript">
functionuploadImage() {
$.ajaxFileUpload({
url:"/Struts2Upload/test/uploadAjax.action",
secureuri:false,
fileElementId:"btn_file",
dataType: "json",
error: function(data, status, e) {
alert(e);
},
success: function(data, textStatus) {
$('img').attr('src',data.imPath);
}
});
}
</script>
依赖的Jar:
5. 修改后看似完美了,不过此代码在Chrome下还是会有一个BUG,因为我用的onchange事件会反复触发fileupload导致多次提交上传,最终的代码如下:
Html:
<div class="upload-w">
<img class="u-img" src="/style/js/upload/update_pic.png" id="img1">
<span class="hide">重新上传</span>
<div class="btn u-btn">
大图上传
<div>
<input class="u-file" type="file" id="btn_file1" name="btn_file1" data-type="big" data-target="img1" />
</div>
</div>
</div>
JavaScript:
$(function(){
$(".u-file[type=file]").live("change",function(){
var url = '/proclass/uploadAjax.action';
var type = $(this).attr("data-type");
var btnName = $(this).attr("id");
var imgName = $(this).attr("data-target");
$.ajaxFileUpload({
url: url,
secureuri:false,
fileElementId:btnName,
dataType: "json",
data: {//加入的文本参数
"photoType": type
},
success: function(data, textStatus) {
$('#'+imgName).attr('src',data.data.imPath);
},
error: function(data, status, e) {
alert("上传的文件不是图片!!");
}
});
});
});
Css:
.upload-w { float:left; margin:10px 20px 10px 0; }
.upload-w .u-img { width:100px; height:100px; border:1px solid #e4e4e4; }
.upload-w .u-btn { position:relative; display:block; text-align:center; }
.upload-w .u-file { position:absolute;left:0;top:0;width:100px;height:100%;z-index:999;opacity:0;filter:alpha(opacity=0); }