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


99

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

Answers:


146

如果您希望使用自己的按钮来上传文件而不是使用<input type="file" />,则可以执行以下操作:

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

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


基本情况下简单明了,但与许多浏览器不兼容。请注意,将这种解决方案与在不透明度为0的按钮上覆盖文件输入元素相结合是一个更好的主意,正如Xeon06的答案中提到的那样。
SquareCat

10
更新:在现代浏览器中,您可以单击甚至不在DOM中的输入。太棒了!
阿德里亚(Adria)2014年

7
我只是想click()display:none输入和它的工作
张国勋

15
是的,在2015年,这里融入click()display: none作品元素!;)在过去四年中情况发生了什么变化。
ffxsam 2015年

您可以hidden改为使用属性style="visibility:hidden"<input id="myInput" type="file" hidden>w3schools.com/tags/att_global_hidden.asp
cespon

113

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

是的,您可以使用jQuery / JavaScript以编程方式单击input元素,但前提是您必须在属于由用户启动的事件的事件处理程序中执行该操作!

因此,例如,如果脚本(脚本)以编程方式单击ajax回调中的按钮,则不会发生任何事情,但是如果将同一行代码放在用户引发的事件处理程序中,它将起作用。

PS debugger;如果在编程性单击之前,至少在chrome 33中,该关键字会破坏浏览窗口。


正如@LouisBataillard正确提及的那样:不仅原始事件处理程序需要由用户启动;它必须专门是单击事件。这是他提供的小提琴,以证明这一点:链接
Souhaieb Besbes

1
您可以单击动态生成的内容。在jquery中,即$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung

1
谢谢!!!!我已经在javascript控制台中测试了所有这些答案,并且发疯了!
jdkealy

8
我一直在半个小时地以编程方式提示文件输入窗口。NOBODY ELSE表示,如果事件不是由用户启动的,那是不可能的……您值得多+1。
Umagon '16

1
从Chrome 62开始,debugger;关键字不再破坏程序化点击
Chris W.

62

仅作记录,还有一种不需要javascript的替代解决方案。利用单击标签将焦点设置在相关输入上这一事实,这有点骇人听闻。

您需要一个<label>具有适当for属性(指向输入)的选项,其样式必须像按钮一样(具有bootstrap,请使用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" />


2
我喜欢这个,不想在我的Angular项目中包含完整的jQuery,效果很好:)
Starscream1984年

1
这种行为在所有现代浏览器中都是可靠的吗?
JoshuaDavid '17年

使用本机浏览器行为,此方法无需使用任何JS。与onDrop事件配对,实现功能丰富的文件上传效果很好!
亚尼克·罗雄

我不得不摆弄CSS,但是随后它起作用了-也就是说,在所有浏览器中都无法正常显示具有“ display:none”的文件输入可见性。(但可以使用不透明度0等)
shiftcatcher

13

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

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

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


5
这似乎仅在“呼叫”事件本身是单击事件时才起作用。例如,似乎无法根据hover事件打开文件对话框:jsfiddle.net/UQfaZ/1
Louis B.

您知道如果输入不在DOM中怎么用Selenium进行测试?
Sebastien Lorber

4

我将包裹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解决方案。


只需设置<input type="file" hidden>即可消除应用CSS样式的需要。
Sylvain Lesage

3

不幸的是,本机唯一的方法是创建一个<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
        })
    })

3

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

<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>

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


1
您应该提到,这需要一个jQuery参考。
布里诺

不透明度涉及一个完全不相关的概念-如果它不影响“透明”元素的布局,那么您很幸运。该元素应该在其中,但不可见,因此visibility:hidden应该是一个更好的选择。
康尼

visibility: hidden仍然会影响布局。display: none是你想要的。
stommestack

1

出于安全原因,没有跨浏览器的方法。人们通常要做的是将输入文件覆盖在其他文件上,并将其可见性设置为隐藏,以便自行触发。更多信息在这里。


2
OP正在谈论<input type="file">,不是<select>
Bojangles

没问题 我自己做过的。在回答您的编辑,有一个办法做到这一点; 通过使用jQuery触发元素的click事件$.click()
Bojangles

1
@JamWaffles好的,这很奇怪。我清楚地记得在几周前花了整整一天的时间。它在Firefox和IE afair中不起作用。我不知道这笔交易是什么...
Alex Turpin

好奇。我的回答中有一个与FF一起使用的JSFiddle。我无法在IE中测试(我在Linux上),所以我不知道这是否还会继续。
Bojangles

2
那里的研究工作不错!如果每次Web开发人员不得不将一些非常正常的行为破解成某种东西时,我都会付出一分钱,那我就会变得肮脏。
Bojangles

1

确保您正在使用绑定在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>)
  }
}



0

对于那些想要相同但正在使用React的人

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"/>

0
<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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.