Как открыть диалог выбора файла через js? - программирование
Подтвердить что ты не робот

Как открыть диалог выбора файла через js?

$('#id').click();

Он не работает в Chrome 26 на Mac OS = (

Проблема заключается в создании виджета "upload", который может быть интегрирован в форму. Виджет будет состоять из двух частей. Первая часть - div с кнопкой инициатора и сообщения об ошибке/успехе. Я думаю, что путь помещается в другую форму как вторую часть с вводом файла и отправкой файла в iframe. После представления мы заполняем скрытое поле в первой части в основной форме или показываем ошибки в том же самом.

Легкий способ добавления файловой формы в основную форму, но это запрещено.

Исправьте меня.

4b9b3361

Ответ 1

Использование jQuery

Я бы создал кнопку и невидимый вход вроде этого

<button id="button">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />

и добавьте несколько jQuery для его запуска:

$('#button').on('click', function() {
    $('#file-input').trigger('click');
});

Использование Vanilla JS

Такая же идея, без jQuery (кредиты @Pascale)

<button onclick="document.getElementById('file-input').click();">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />

Ответ 2

Только JS - нет необходимости в jquery

Просто создайте элемент ввода и запустите щелчок.

var input = document.createElement('input');
input.type = 'file';
input.click();

Это самое простое, всплывающее диалоговое окно выбора файла, но его бесполезно без обработки выбранного файла...

Обработка файлов

Добавление события onchange во вновь созданный вход позволит нам делать что-то, как только пользователь onchange файл.

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 
   var file = e.target.files[0]; 
}

input.click();

На данный момент у нас есть файловая переменная, хранящая различную информацию:

file.name // the file name including extension
file.size // the size in bytes
file.type // file type ex. 'application/pdf'

Большой!

Но что, если нам нужно содержимое файла?

Для того, чтобы получить фактическое содержание файла, по разным причинам. поместите изображение, загрузите на холст, создайте окно с URL-адресом Base64 и т.д. нам нужно будет использовать API FileReader

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

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsText(file,'UTF-8');

   // here we tell the reader what to do when it done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      console.log( content );
   }

}

input.click();

При попытке вставить приведенный выше код в ваше окно консоли devtool, должно появиться диалоговое окно выбора файла, после выбора файла консоль теперь должна распечатать содержимое файла.

Пример - "Stackoverflow новое фоновое изображение!"

Давайте попробуем создать диалог выбора файла, чтобы изменить фоновое изображение stackoverflows на что-то более пряное...

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsDataURL(file); // this is reading as data url

   // here we tell the reader what to do when it done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      document.querySelector('#content').style.backgroundImage = 'url('+ content +')';
   }

}

input.click();

откройте devtools и вставьте приведенный выше код в окно консоли, после чего должно появиться диалоговое окно выбора файла, при выборе изображения фон окна содержимого stackoverflow будет меняться на выбранное изображение.

Ура!

Ответ 3

Только в HTML:

<label>
  <input type="file" name="input-name" style="display: none;" />
  <span>Select file</span>
</label>

Изменить: я не проверял это в Blink, он на самом деле не работает с <button>, но он должен работать с большинством других элементов - по крайней мере, в последних браузерах.

Проверьте эту скрипку с кодом выше.

Ответ 4

Для полноты, Рон ван дер Хейден решение в чистом JavaScript:

<button onclick="document.querySelector('.inputFile').click();">Select File ...</button>
<input class="inputFile" type="file" style="display: none;">

Ответ 5

Чтобы расширить ответ от 'levi' и показать, как получить ответ от загрузки, чтобы вы могли обработать загрузку файла:

selectFile(event) {
    event.preventDefault();

    file_input = document.createElement('input');
    file_input.addEventListener("change", uploadFile, false);
    file_input.type = 'file';
    file_input.click();
},

uploadFile() {
    let dataArray = new FormData();
    dataArray.append('file', file_input.files[0]);

    // Obviously, you can substitute with JQuery or whatever
    axios.post('/your_super_special_url', dataArray).then(function() {
        //
    });
}

Ответ 6

ГОТОВ ИСПОЛЬЗОВАТЬ ФУНКЦИЮ (используя Promise)

/**
 * Select file(s).
 * @param {String} contentType The content type of files you wish to select. For instance "image/*" to select all kinds of images.
 * @param {Boolean} multiple Indicates if the user can select multiples file.
 * @returns {Promise<File|File[]>} A promise of a file or array of files in case the multiple parameter is true.
 */
function (contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = _ => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}

ПОПРОБУЙ ЭТО

// Content wrapper element
let contentElement = document.getElementById("content");

// Button callback
async function onButtonClicked(){
    let files = await selectFile("image/*", true);
    contentElement.innerHTML = files.map(file => '<img src="${URL.createObjectURL(file)}" style="width: 100px; height: 100px;">').join('');
}

// ---- function definition ----
function selectFile (contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = _ => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}
<button onclick="onButtonClicked()">Select images</button>
<div id="content"></div>

Ответ 7

Сначала объявите переменную для хранения имен файлов (чтобы использовать их позже):

var myfiles = [];

Диалог открытия файла

$('#browseBtn').click(function() {
    $('<input type="file" multiple>').on('change', function () {
        myfiles = this.files; //save selected files to the array
        console.log(myfiles); //show them on console
    }).click();
});

Я публикую это, так что это может кому-то помочь, потому что в интернете нет четких инструкций о том, как хранить имена файлов в массиве!