Програмно запустити діалогове вікно "вибрати файл"


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вході, і це спрацювало
Даніель Чен

15
Так, ось, у 2015 році, ми click()бачимо елемент із display: noneтворами! ;) Як змінилися справи за останні чотири роки.
ffxsam

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

113

Більшість відповідей тут не має корисної інформації:

Так, ви можете програмно клацнути елемент введення за допомогою jQuery / JavaScript, але тільки якщо ви це робите в обробці подій, що належить до події, ЩО ЗАПОЧАЛИ ПОТРІБНИК!

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

PS debugger;Ключове слово порушує вікно перегляду, якщо воно перебуває до програмного клацання ... принаймні в хромірованному 33 ...


як справедливо зазначає @LouisBataillard: не тільки оригінальний обробник подій повинен бути ініційований користувачем; це має бути конкретно подія клацання. Ось
загадка, яку він наводив,

1
ви можете натиснути щось, що динамічно генерується. в jquery, тобто$(staticElementParent).on("click", "dynamicChild", function(){})
Даніель Чеунг

1
СПАСИБІ!!!! Я випробовував усі ці відповіді на консолі javasv, і я накрутився!
jdkealy

8
Я півтора години боровся з програмним підштовхуванням вікна введення файлів. NOBODY ELSE заявив, що це неможливо, якщо подія не розпочнеться користувачем ... ти заслуговуєш багато +1.
Умагон

1
Станом на Chrome 62, debugger;ключове слово більше не порушує програмне клацання
Chris W.

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
чи така поведінка надійна у всіх сучасних браузерах?
ДжошуаДавид

Це працює без будь-якого 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 Лесаж

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повинен бути кращим вибором.
conny

visibility: hiddenяк і раніше впливає на макет. display: noneце те, що ти хочеш.
stommestack

1

Немає крос-браузерного способу зробити це з міркувань безпеки. Те, що зазвичай роблять люди, - це накладання вхідного файлу на щось інше і встановлення його видимості прихованим, так що він спрацьовує самостійно. Більше інформації тут.


2
Про ОП говорять <input type="file">, ні <select>.
Bojangles

Не проблема. Я робив це сам раніше. У відповідь на вашу редакцію, є спосіб це зробити; запустивши подію клацання елемента за допомогою jQuery $.click().
Bojangles

1
@JamWaffles добре, це дивно. Я чітко пам’ятаю, що цілий день витрачав на це кілька тижнів тому. Це не працювало в Firefox та IE afair. Цікаво, яка угода була ...
Олексій Турпін

Цікавий. У своїй відповіді є 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

За допомогою jQuery ви можете зателефонувати, click()щоб імітувати клацання.



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.