Программно запускать диалоговое окно «Выбрать файл»


100

У меня есть скрытый элемент ввода файла. Можно ли вызвать диалоговое окно выбора файла из события нажатия кнопки?

Ответы:


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. Вы не можете вызвать событие щелчка для не отображаемого ввода файла.


Простой для базовых случаев, но не совместим со многими браузерами. Обратите внимание, что гораздо лучше объединить это решение с наложением элемента ввода файла на кнопку с непрозрачностью: 0, как было упомянуто в ответе Xeon06.
SquareCat

10
Обновление: в современных браузерах вы можете щелкнуть ввод, которого нет даже в DOM. Потрясающие!
Адрия

7
я просто пытался click()на display:noneвходе , и она работала
Daniel Cheung

15
Ага, вот в 2015 году click()работаю над элементом с display: noneработами! ;) Как все изменилось за последние четыре года.
ffxsam

hiddenВместо этого вы можете использовать атрибут style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
cespon

115

В большинстве ответов здесь отсутствует полезная информация:

Да, вы можете программно щелкнуть элемент ввода с помощью jQuery / JavaScript, но только если вы делаете это в обработчике событий, принадлежащем событию, которое было запущено ПОЛЬЗОВАТЕЛЕМ!

Так, например, ничего не произойдет, если вы, сценарий, программно нажмете кнопку в обратном вызове ajax, но если вы поместите ту же строку кода в обработчик событий, который был вызван пользователем, он будет работать.

PS debugger;Ключевое слово срывает окно просмотра, если оно до программного щелчка ... хотя бы в хроме 33 ...


как справедливо отмечает @LouisBataillard: не только исходный обработчик событий должен быть инициирован пользователем; это должно быть событие щелчка. Вот скрипка, которую он предоставил, демонстрируя это: ссылка
Souhaieb Besbes

1
вы можете щелкнуть то, что создается динамически. в jquery, то есть$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung

1
СПАСИБО!!!! Я тестировал все эти ответы в консоли javascript и сходил с ума!
jdkealy

8
Я полчаса борюсь с программным запросом окна ввода файла. НИКТО ЭТО НЕ заявил, что это невозможно, если событие не запускается пользователем ... вы заслуживаете много +1.
Умагон

1
Начиная с Chrome 62 debugger;ключевое слово больше не мешает программному клику
Крис В.

62

На заметку, есть альтернативное решение, не требующее javascript. Это своего рода уловка, использующая тот факт, что щелчок по метке устанавливает фокус на связанный ввод.

Вам нужен атрибут <label>с правильным forатрибутом (указывает на ввод), возможно, стилизованный как кнопка (с начальной загрузкой, используйте 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
Мне нравится этот, не хочу включать полный jQuery в мой проект Angular, отлично работает :)
Starscream1984

1
надежно ли такое поведение во всех современных браузерах?
JoshuaDavid

Это работает без какого-либо JS, используя собственное поведение браузера. В сочетании с событиями onDrop реализация многофункциональной загрузки файлов отлично работает!
Яник Рочон

Мне пришлось возиться с CSS, но потом это сработало - а именно, видимость входного файла, имеющая "display: none", не подходит для всех браузеров. (Но можно использовать непрозрачность 0 и т. Д.)
driftcatcher

13

Я не уверен, как браузеры обрабатывают щелчки по type="file"элементам (проблемы безопасности и все такое), но это должно работать:

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

Я тестировал этот JSFiddle в Chrome, Firefox и Opera, и все они отображают диалог просмотра файлов.


5
Похоже, это работает только тогда, когда «вызывающее» событие само является событием щелчка. Например, не представляется возможным открыть диалоговое окно файла на основе hoverсобытия: jsfiddle.net/UQfaZ/1
Луи Б.

Вы знаете, как это можно проверить с помощью Selenium, если ввод не находится в DOM?
Себастьен Лорбер,

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">элемент, а затем, к сожалению, имитировать щелчок.

Есть крошечный плагин (бесстыдный плагин), который избавит от необходимости делать это все время: file-dialog

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это лучший выбор.
conny

visibility: hiddenпо-прежнему влияет на макет. display: noneэто то, что вы хотите.
Stommestack

1

По соображениям безопасности кроссбраузерного способа сделать это невозможно. Обычно люди накладывают входной файл на что-то еще и устанавливают его видимость как скрытую, чтобы он запускался сам по себе. Больше информации здесь.


2
ОП говорит <input type="file">, а не о <select>.
Bojangles

Не проблема. Я сам делал это раньше. В ответ на ваши изменения, то есть способ сделать это; путем запуска события щелчка элемента с помощью jQuery $.click().
Bojangles

1
@JamWaffles, ладно, это странно. Я ясно помню, как несколько недель назад потратил на это целый день. Это не работало в Firefox и IE. Интересно, в чем заключалась сделка ...
Алекс Терпин

Любопытно. В моем ответе есть JSFiddle, который работает с FF. Я не могу тестировать в IE (я использую Linux), поэтому я не знаю, будет ли это по-прежнему рваться.
Bojangles

2
Хорошие исследования! Если бы я тратил копейки за каждый раз, когда веб-разработчикам приходилось прибегать к чему-то довольно нормальному поведению, я был бы чертовски богат.
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>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.