js美化html上传按钮控件的方法

html中有几个比较难美化的控件,比如checkbox、radio、select,还有这篇博文的重点——上传控件。下面就说说怎么美化。

简短的说明

事实上,在html上传控件原本的基础上美化目前是不可能的,主流的浏览器都无法使用css样式表对丑陋的上传控件进行美化,只能另辟蹊径,隐藏掉原本丑陋的控件,用其他元素代替原本的样子,”改头换面”后,控件就能成为自己或者说符合UI的审美。
这样的话,css和html打头阵尤为重要,如下代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<style>
*{
padding:0;
margin:0;
}
.input-file>label>input[type=file] {
display: none;
}
.input-file>label>label {
display: inline-block;
padding: 0;
width: 90px;
height: 30px;
background-color: orange;
color: #fff;
font-size: 16px;
font-weight: 600;
text-align: center;
line-height: 30px;
border-radius: 3px;
}
.input-file>label>span {
display: inline-block;
}
</style>
<div class="input-file">
<label>
<input type="file" name='customer_id_data' id="fileUp" />
<label for="fileUp">选择</label>
<span class="file-name-hook">未选择文件</span>
</label>
</div>

可能有人问label标签套个label是什么鬼,我只能说,这样做是为了有个假按钮代替原有丑陋的按钮,同时这个假按钮又和原来丑按钮一样的点击弹出文件选择的效果,label和input毕竟是老搭档,如下手册原文的解释:

1
2
3
4
5
6
定义和用法
<label> 标签为 input 元素定义标注(标记)。
label 元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果您在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
<label> 标签的 for 属性应当与相关元素的 id 属性相同。
提示和注释:
注释:"for" 属性可把 label 绑定到另外一个元素。请把 "for" 属性的值设置为相关元素的 id 属性的值。

重头戏JavaScript(顺便带一个简单的文件格式验证)

为了方便,当然是要引用jQ。
详细的说明和代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$(document).on('change', '#fileUp', function() {
var str = $(this).val();
console.log(str);
// 上面在控制台输出的是‘C:\fakepath\test.xlsx’,
var strArr = str.split('\\');
// 获取最后一个'\'后面的字符串,获取后缀名
var fileName = strArr[strArr.length - 1];
var strSuf = fileName.split('.');
strSuf = strSuf[strSuf.length - 1];
// 定义一个希望上传文件正确格式数组,这里用excel文件格式为例
var format = ['xlsx', 'xls'];
// 判断当前上传文件格式是否正确
// 正确:将文件名同步到'.file-name-hook'
// 错误:复制出上传控件追加到原控件后面,并且删除原控件
if (format.indexOf(strSuf) > -1) {
$('.file-name-hook').text(fileName);
return false;
} else {
alert('文件格式不正确');
$('#fileUp').after($('#fileUp').clone().val(""));
$('#fileUp').remove();
$('.file-name-hook').text('未选择文件');
return false;
}
});

这里事件引用方法为何是‘on()’?而不是‘change()’,或者‘bind(‘change’,function(){}),是有学问的。最后格式错误是要复制出上传控件追加到原控件后面,并且删除原控件的,这样一次错误格式操作之后,方法‘change()’和‘bind(‘change’,function(){})’是失效的。

1
2
3
4
5
6
7
8
9
10
11
定义和用法
on() 方法在被选元素及子元素上添加一个或多个事件处理程序。
语法
$(selector).on(event,childSelector,data,function)
|参数 |描述 |
| ------------- |:-------------:|
|event |必需。规定要从被选元素移除的一个或多个事件或命名空间。由空格分隔多个事件值,也可以是数组。必须是有效的事件。|
|childSelector |可选。规定只能添加到指定的子元素上的事件处理程序(且不是选择器本身,比如已废弃的 delegate() 方法)。|
|data |可选。规定传递到函数的额外数据。|
|function |可选。规定当事件发生时运行的函数。|

好了,这就完结了,路过的大神不吝赐教,互相学习。