1. FILE 控件的美化
【错误示例】file控件的美化,我们想到的方法是将FILE控件本身隐藏,然后使用div+css模拟一个FILE控件,当用户单击这个模拟的FILE控件时,再触发隐藏的真实的FILE控件的单击事件,进而打开本地文件选择框。这种方式会遇到一个浏览器安全问题,并且JavaScript会提示拒绝访问的错误。
<!--- html 代码片段 --->
<div id="fake_file_ctrl">
<img src="beatiful_upload_btn.png"/>
</div>
<input type="file" class="hidden_ctrl" id="file_upload" name="file_upload"/>
//javascript 代码片段
$("#fake_file_ctrl").click(function(){
$("#file_upload").trigger("click");
//此句出错,在IE浏览器下会提示拒绝访问。
});
【正确示例】上面错误示例中的思路是正确的,但是如何避免拒绝访问的错误呢?既然JavaScript找不到出路,那只好寻求CSS了.原理如下: 将实际的FILE控件透明地覆盖在模拟控件上,这样当用户单击模拟控件的时候,同时也单击了实际的FILE控件。
#fake_file_ctrl{
position:relative;
left:0px;
top:0px;
width:400px;
height:200px;
}
#file_upload{
position:relative;
left:0px;
top:-200px; /* 将实际的FILE控件和模拟FILE控件重叠*/
width:400px;
height:200px;
opacity:0; /* 完全透明 支持opacity的浏览器*/
filter:alpha(opacity=0); /* IE浏览器 */
-moz-opacity:0; /* 老版Mozilla */
-khtml-opacity:0; /* 老版Safari */
}
2. ajaxUploadFile.js文件异步提交的问题
我们知道,在HTML中直接单击input控件上传图片文件的时候会跳转到文件上传处理页面,导致本页面刷新,用户体验非常糟糕。利用ajaxUploadFile.js这样的jQuery异步上传插件可以避免上述情况。这个插件本身也有很多局限(不能选择多个文件同时上传,不能在上传文件的同时提交附加参数),好在第二个局限可以通过修改ajaxUploadFile.js源代码进行弥补。实际使用过程中可能还会遇到其他的问题,具体如下:
2.1 运行时报错:jQuery.handleError is not a function
这个错误是由于ajaxfileupload.js 是在jquery1.4.2版本之前写的,Jquery之后的版本已经没有了handleError 方法,所以可以将1.4.2版本中的该方法复制到该js中。
//handleError 方法在jquery1.4.2之后移除了,此处重写改方法
//注意这个方法在ajaxUploadFile.js添加的正确位置。在所有handleError方法调用之前。
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] );
}
},
2.2 无法提交附加参数,只能上传文件
需要修改ajaxUploadFile.js源代码,改动的地方有两个.
第一处是 将原createUploadForm: function(id, fileElementId) 方法添加一个data参数,并将data中的数据拼接进去即可。代码如下:
createUploadForm: function(id, fileElementId,data) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
// 增加参数的支持
if (data) {
for (var i in data) {
$('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
第二处是 调用createUploadForm方法地方,如下所示:
ajaxFileUpload: function(s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime();
/******** 修改代码 支持上传额外参数 *******/
// var form = jQuery.createUploadForm(id, s.fileElementId);
var form = jQuery.createUploadForm(id, s.fileElementId, s.data); //新增这一句,替换上面注释的语句
var io = jQuery.createUploadIframe(id, s.secureuri);
2.3 执行成功后,始终指向error方法,无法执行sucess方法
这个是由于ajaxfileupload.js 处理返回data的时候,没有考虑后台返回的是字符串的情况。需要修改uploadHttpData方法:
if ( type == "json" ){
// 如果返回的是字符串(JSON格式字符串),下面会报错,导致无法进入sucess方法 加上"引号转化为字符串后就没事了。
// eval( "data = " + data );//注释掉这一句
eval('data = " '+data+' " ');
}
<<<先整理到这,后续补充. ^_^