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


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.