以编程方式触发“选择文件”对话框

我有一个隐藏的文件输入元素。是否可以从按钮的单击事件触发其 选择文件对话框?

129417 次浏览

There is no cross browser way of doing it, for security reasons. What people usually do is overlay the input file over something else and set it's visibility to hidden so it gets triggered on it's own. More info here.

使用 jQuery,您可以调用 click()来模拟单击。

我不确定浏览器如何处理对 type="file"元素的点击(安全问题和所有问题) ,但这应该可行:

$('input[type="file"]').click();

我已经在 Chrome、 Firefox 和 Opera 中测试了 这个 JSFiddle,它们都显示了文件浏览对话框。

如果你想拥有自己的按钮来上传文件而不是使用 <input type="file" />,你可以这样做:

<input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />

请注意,我使用的是 visibility: hidden,而不是 display: none。您不能对未显示的文件输入调用点击事件。

这里的大多数答案都缺乏有用的信息:

是的,您可以使用 jQuery/JavaScript 通过编程方式单击输入元素,但只有在属于由用户启动的事件的事件处理程序中才可以这样做!

因此,例如,如果脚本通过编程方式单击 ajax 回调中的按钮,那么不会发生任何事情,但是如果在用户引发的事件处理程序中放入相同的代码行,则会正常工作。

另外,如果 debugger;关键字在程序化点击之前打断浏览窗口,至少在 chrome 33中是这样的。

最好的解决方案,适用于所有浏览器. . 甚至是移动设备。

<div class="btn" id="s_photo">Upload</div>


<input type="file" name="s_file" id="s_file" style="opacity: 0;">';


<!--jquery-->


<script>
$("#s_photo").click(function() {
$("#s_file").trigger("click");
});
</script>

隐藏输入文件类型会导致浏览器出现问题,不透明是最好的解决方案,因为它没有隐藏,只是没有显示。:)

这对我很有效:

$('#fileInput').val('');

只是为了记录,有一个不需要 javascript 的替代解决方案。利用点击标签将焦点集中在相关输入这一事实,这有点像一种技巧。

您需要一个具有适当 for属性(指向输入)的 <label>,可选的样式类似于按钮(通过引导,使用 btn btn-default)。当用户单击标签时,对话框打开,例如:

<!-- optionnal, to add a bit of style -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>


<!-- minimal setup -->
<label for="exampleInput" class="btn btn-default">
Click me
</label>
<input type="file" id="exampleInput" style="display: none" />

不幸的是,本来唯一的方法是创建一个 <input type="file">元素,然后模拟单击。

有一个小插件(不知羞耻的插件) ,它将带走痛苦的所有时间这样做: 文件对话框

fileDialog()
.then(file => {
const data = new FormData()
data.append('file', file[0])
data.append('imageName', 'flower')


// Post to server
fetch('/uploadImage', {
method: 'POST',
body: data
})
})

我将 input[type=file]包装在一个标签标记中,然后按照您的喜好设置 label的样式,并隐藏 input

<label class="btn btn-default fileLabel" data-toggle="tooltip" data-placement="top" title="Upload">
<input type="file">
<span><i class="fa fa-upload"></i></span>
</label>


<style>
.fileLabel input[type="file"] {
position: fixed;
top: -1000px;
}
</style>

纯 CSS 解决方案。

对于那些想要同样的,但正在使用反应

openFileInput = () => {
this.fileInput.click()
}

<a href="#" onClick={this.openFileInput}>
<p>Carregue sua foto de perfil</p>
<img src={img} />
</a>
<input style=\{\{display:'none'}} ref={(input) => { this.fileInput = input; }} type="file"/>

确保在 REACT 中使用绑定来获取组件道具

class FileUploader extends Component {
constructor (props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
onChange=(e,props)=>{
const files = e.target.files;
const selectedFile = files[0];
ProcessFileUpload(selectedFile,props.ProgressCallBack,props.ErrorCallBack,props.CompleatedCallBack,props.BaseURL,props.Location,props.FilesAllowed);
}
handleClick = () => {
this.refs.fileUploader.click();
}
render()
{
return(
<div>
<button type="button" onClick={this.handleClick}>Select File</button>
<input type='file' onChange={(e)=>this.onChange(e,this.props)} ref="fileUploader" style=\{\{display:"none"}} />
</div>)
}
}
<div id="uploadButton">UPLOAD</div>
<form action="[FILE_HANDLER_URL]" style="display:none">
<input id="myInput" type="file" />
</form>
<script>
const uploadButton = document.getElementById('uploadButton');
const myInput = document.getElementById('myInput');


uploadButton.addEventListener('click', () => {
myInput.click();
});
</script>

如今,像这样的混合解决方案可以获得最佳体验,

let fileHandle;
async function fileOpen() {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
console.log(await file.text());
}
// The advantage of this is fileHandle can be used to save to
// the opened file itself later, read more on this in https://web.dev/file-system-access/




// in April 2021, window.showOpenFilePicker still not support in Safari
// so one should have this around also
function legacyFileOpen() {
var input = document.createElement('input');
input.type = 'file';
input.onchange = function () {
input.files[0].arrayBuffer().then(function (arrayBuffer) {
console.log(new TextDecoder().decode(arrayBuffer));
});
}
input.click();
}

以编程方式浏览文件




function browseFile(accept) {
const promise = resolvingPromise();
const input = document.createElement('input');
input.type = "file";
input.accept = accept;
input.onchange = function (e) {
const files = e.target.files;
promise.resolve(files);
}
setTimeout(function () {
click(input);
}, 0);
return promise;
}


function click(node) {
try {
node.dispatchEvent(new MouseEvent('click'))
} catch (e) {
const evt = document.createEvent('MouseEvents')
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null)
node.dispatchEvent(evt);
}
}