如何主動喚起文件選擇框

如題,搞過文件上傳的,確定會有這種想法,也是初學者常常犯的「誤區」html

let input = document.createElement('input');
input.type = 'file';
input.click();

像我這樣經驗老道的,一看,「不可能,這會受到瀏覽器安全策略限制」,牛逼哄哄的祭出正解瀏覽器

solution

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腳本,適用於簡單樸素的原生表單。

到目前爲止,所謂"強壯的"的衆多上傳控件,仍然在使用慣用伎倆,這種不優雅的方式,早該被淘汰了,該是重構的時候了。

相關文章
相關標籤/搜索