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


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.