共计 7307 个字符,预计需要花费 19 分钟才能阅读完成。
目录
前言
本文主要是利用 跟 js 做一些按钮样式功能跟样式上的自定义。并考虑了兼容性、js 禁用、浏览器 bug。主要思路如下:
- 隐藏
- 给
定义样式充当上传按钮
- 用 js 获得选定的文件名与数量
我们先来看一个单纯的 input:
ol class=“linenums”>li class=“L0”>code>span class=“tag”>input/span> pan>span class=“atn”>type/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>name/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>id/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>class/span>=pan>span class=“atv”>“inputfile”/span> pan>span class=“tag”>/>pan>/code>/li>
|
接下来开始一步步优化这个文件选择按钮。
隐藏 Input
首先我们先把难看的输入框隐藏起来。注意这时是不能用 display: none
或 visibility: hidden
的。理由是:这样做的话 input 的值就无法通过 submit 发送到服务器,input 按钮也无法被 tab 键被选中。我们可以使用一些 css 属性隐藏 input 同时让它对浏览器是可见的:
ol class=“linenums”>li class=“L0”>code>span class=“pun”>./span>inputfile pan>span class=“pun”>{/span>/code>/li> widthpan>span class="pun">:/span> pan>span class="lit">0.1px/span>;pan>/code>/li> |
这里解释下为什么把 width
和 height
设置为 0.1px
而不是 0px
, 把宽高设成 0 的话在一些浏览器中会被排除在 tab 键选择之外。另外 position: absolute;
可以保证它不会影响周围元素。
给 Label 定义样式
主要就是让 看起来像个按钮,简单的写一下:
ol class=“linenums”>li class=“L0”>code>span class=“pun”>./span>inputfile pan>span class=“pun”>+/span> label pan>span class=“pun”>{/span>/code>/li> fontpan>span class="pun">-/span>sizepan>span class="pun">:/span> pan>span class="lit">1.25em/span>;pan>/code>/li> |
网页无障碍 Web Accessibility
为了让效果更友好,我们需要让按钮被选中时产生变化,以便让用户知道按钮被选中了。
我们先让鼠标覆盖到按钮上时变成小手:
ol class=“linenums”>li class=“L0”>code>span class=“pun”>./span>inputfile pan>span class=“pun”>+/span> label pan>span class=“pun”>{/span>/code>/li> cursorpan>span class="pun">:/span> pointerpan>span class="pun">;/span> pan>span class="com">/* "hand" cursor *//span>/code>/li> |
键盘导航
某些用户只能使用键盘来操作页面,我们得让按钮被聚焦到时产生点变化表示被选中,以便这些用户操作。可以使用 css 选择器:
ol class=“linenums”>li class=“L0”>code>span class=“pun”>./span>inputfilepan>span class=“pun”>:/span>focus pan>span class=“pun”>+/span> label pan>span class=“pun”>{/span>/code>/li> outlinepan>span class="pun">:/span> pan>span class="lit">1px/span> dotted pan>span class="com">#000;/span>/code>/li> |
提示:-webkit-focus-ring-color auto 5px
可以在 Chrome, Opera 和 Safari 显示的像一个默认的外框线。在非 webkit 浏览器下则使用第一条 outline 规则。
可能出现的点击问题
如果你使用FastClick(一个用来处理移动端 click
事件 300 毫秒延迟的库)并且打算在 lable
里加一些标签,按钮可能就无法工作了。可以使用 pointer-events: none
来解决这个问题:
ol class=“linenums”>li class=“L0”>code>span class=“tag”>label/span> pan>span class=“atn”>for/span>=pan>span class=“atv”>“file”/span>>pan>span class=“pln”>Choose a file/span>trong>/label>pan>/code>/li>/ol> |
ol class=“linenums”>li class=“L0”>code>span class=“pun”>./span>inputfile pan>span class=“pun”>+/span> label pan>span class=“pun”>*/span> pan>span class=“pun”>{/span>/code>/li> pointerpan>span class="pun">-/span>eventspan>span class="pun">:/span> nonepan>span class="pun">;/span>/code>/li> |
提示:pointer-events: none
在解决点击穿透问题时还是很好用的,具体的相关介绍可以查看张鑫旭大神的这篇文章:CSS3 pointer-events:none 应用举例及扩展
通过 JavaScript 改善
我们还需要能够显示选择了多少文件,input
是能够做到这个的,但是我们已经把它给隐藏了。我们可以使用一点点 js 让 lable
的内容变成选择的文件名或数量。
ol class=“linenums”>li class=“L0”>code>span class=“tag”>input/span> pan>span class=“atn”>type/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>name/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>id/span>=pan>span class=“atv”>“file”/span> pan>span class=“atn”>class/span>=pan>span class=“atv”>“inputfile”/span> pan>span class=“atn”>data–multiple–caption/span>=pan>span class=“atv”>“{count} files selected”/span> pan>span class=“atn”>multiple/span> pan>span class=“tag”>/>pan>/code>/li>/ol> |
ol class=“linenums”>li class=“L0”>code>span class=“kwd”>var/span> inputs pan>span class=“pun”>=/span> documentpan>span class=“pun”>./span>querySelectorAllpan>span class=“pun”>(/span> pan>span class=“str”>‘.inputfile’/span> pan>span class=“pun”>);/span>/code>/li> Arraypan>span class="pun">./span>prototypepan>span class="pun">./span>forEachpan>span class="pun">./span>callpan>span class="pun">(/span> inputspan>span class="pun">,/span> pan>span class="kwd">function/span>(pan>span class="pln"> input /span>)pan>/code>/li> |
文章来源: 使用 css 及 js 自定义文件上传按钮