文件上传控件<input type="file"/>在不同的浏览器下,显示为不同的样式,并且很难随着不同的设计而进行对应变化,这里将实现一种jquery插件的方法,实现用户自己自定义样式的文件上传控件。
先来看下在不同浏览器下,该控件的显示:
图一:
图二:
由以上两个图我们可以得到几个结论:
1、不同浏览器下,该控件的显示外观有很大不同。
2、在ie下,控件显示文件路径;在其他浏览器下,控件显示文件名。
3、无论怎样改变控件的宽度,控件的”浏览button“(或者文件上传button)的宽度不变(64px)。
还有隐藏的第四个特点:
4、在ie下,只有"浏览button"可点击;而其他浏览器下,文本显示区域也可以点击。
最初的时候,为了达到完全的统一,我的处理思路是:将真的<input type="file" />控件隐藏,用图片制作一个假的控件,当点击图片时,触发真控件的click事件,从而达到外表统一,又完成文件上传的目的。
但是,最终这种方法失败了。经闯闯同学指点,该方法在ie下会触发安全问题。
原因是:这种间接上传文件的方式,被ie认为是不安全的,将阻止文件向服务器传送。所以说,样式处理好了,功能还是没处理好。
最后解决办法:
将真的控件设置为透明的,浮在图片上。
这种情况下,伪控件图片设计就需要考虑之前提到的第3和第4个问题。
最终代码如下:
<body>
<input type="file" id="fileControl" value="选择文件"/>
</body>
jQuery.fn.extend({
fileControl:function(){
var argus = arguments[0];
return this.each(function(){
var paddingLeft = argus.paddingLeft,
width = argus.width?argus.width:$(this).width()-(paddingLeft?paddingLeft:0),
height = argus.height?argus.height:$(this).height(),
top = argus.top?argus.top:($(this).height()+parseInt(($(this).outerHeight() - $(this).height())/2)),
left = argus.left?argus.left:($(this).width()+parseInt(($(this).outerWidth() - $(this).width())/2)),
lineHeight = argus.lineHeight?argus.lineHeight:height,
//设置伪控件样式
style = "position:relative; z-index:-1; background-position:top left; background-repeat:no-repeat;left:0px;top:-"+height+"px;";
style += argus.image?("background-image:url("+argus.image+");"):"";
style += "width:"+width+"px;";
style += height?("height:"+height+"px;"):"";
style += paddingLeft?("padding-left:"+paddingLeft+"px;"):"";
style += lineHeight?("line-height:"+lineHeight+"px;"):"";
$(this).wrap("<div></div>").after("<div id='fadeFile' ></div>").css({"width":"64px","opacity":"0"})
.next().attr("style",style);
$(this).change(function(){
showFile($(this),$(this).next());
});
function showFile(telem,felem){
var value = $(telem).val(),
pos = -1;
if((pos = value.lastIndexOf("\\")) != -1){
value = value.slice(pos+1);
}
$(felem).text(value);
}
});
}
});
调用方法:
$(fileElem).fileControl(obj);
其中的fileElem为文件上传控件对象,obj为属性对象,包括以下属性:
image:伪控件图片路径。必须项。
width:图片宽。必须项。
height:图片高。必须项。
paddingLeft:控制上传文件名的显示横向位置。可选;默认值为0。
top:伪控件距离原控件起点的位置的上边距。可选;正值;默认为真控件的(高+(外高-高)/2)
left:伪控件距离原控件起点的位置的左边距。可选;正值;默认为真控件的(宽+(外宽-宽)/2)
lineHeight:文件名显示的纵向位置。可选;默认值为真控件的高。
例子:
$("#fileControl").fileControl({"image":"file.png","width":"505","height":"27","paddingLeft":"70"});
实现结果:
代码:
控件:
该控件优点:
1、比较灵活:用户可根据自己的设计,调整控件的位置、文字显示位置等属性。
2、文件名显示:可以将路径和文件名在ie浏览器下的不统一,控制成显示为统一的文件名。
3、遵循web开发的“平稳退化”原则:伪控件的dom元素及样式均由js动态生成,在不支持js的情况下,人能正常的表达页面,并完成文件上传功能。