如題,搞過文件上傳的,確定會有這種想法,也是初學者常常犯的「誤區」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腳本,適用於簡單樸素的原生表單。
到目前爲止,所謂"強壯的"的衆多上傳控件,仍然在使用慣用伎倆,這種不優雅的方式,早該被淘汰了,該是重構的時候了。