如题,搞过文件上传的,确定会有这种想法,也是初学者常常犯的“误区”html
let input = document.createElement('input'); input.type = 'file'; input.click();
像我这样经验老道的,一看,“不可能,这会受到浏览器安全策略限制”,牛逼哄哄的祭出正解浏览器
让 input[type=file]
飘在点击区上方,老手的惯用伎俩,这就叫“经验”,但最近一些事,让我啪啪打脸,颠覆了个人认知,不信你试试在 Chrome 的 Console 中试一下上面的三行代码。安全
。。。。。。spa
是否是很意外,让你在 Chrome 中试,是由于目前好像只有 Chrome 能这么大胆的放开,让你这么放肆,咱们再尝试在 Safari 下试一下设计
。。。。。。code
好像没效果,咱们可联想到,浏览器限制这些东西,无非是想肯定是人为操做,而非自动运行,在不少相似的情形,都有相似要求“人机交互事件发生时”,好比用户点击、键盘敲击。咱们能够这么尝试一下htm
<input id="file" type="file" style="display:none" /> <button id="trigger">选择</button> <script> let input = document.getElementById('file'); document.getElementById('trigger').onclick = function () { input.click(); }; </script>
这种状况很适合那种,“原生的input
的太丑,我想弄个漂亮的按钮触发上传”、“我想更优雅的控制上传”事件
还有一种状况我想在输入域中输入某个命令,回车触发上传ip
<input id="file" type="file" style="display:none" /> <div id="trigget" contenteditable>敲击回车触发上传</div> <script> let input = document.getElementById('file'); document.getElementById('trigger').onkeypress = function (e) { e.preventDefault(); input.click(); }; </script>
浏览器兼容性以下rem
Ability | IE | Firefox(41) | Safari(11) | Chrome(65) |
---|---|---|---|---|
直接唤起 | no | no | no | yes |
事件沙盒(click/keyup)唤起 | 8,9,10,11 | yes | yes | yes |
能够说是全兼容。
有些版本我懒得测了,但我想连IE8都行,其它的不用测了吧
IE 下,input[type=file]
须要存在文档流中
至此,我想你以前经历过的,input
飘在某个按钮上方这种别扭设计能够扔掉了。
可是还没完,不知道你们有没有想到 labelFor
的应用场景,若是只是想点击事件转移,咱们能够尝试如下方案
<input id="file" type="file" style="display:none" /> <label for="file"> <span>点击上传</span> </label>
或者
<label> <span>点击上传</span> <input type="file" style="display:none" /> </label>
这种方式,属于html原生支持的、设计如此的,不须要一句js脚本,适用于简单朴素的原生表单。
到目前为止,所谓"强壮的"的众多上传控件,仍然在使用惯用伎俩,这种不优雅的方式,早该被淘汰了,该是重构的时候了。