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

#javascript #html #simulation

#javascript #jquery #HTML

Вопрос:

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

Ответ №1:

Если вы хотите иметь собственную кнопку для загрузки файла вместо использования <input type="file" /> , вы можете сделать что-то вроде:

 <input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />
 

Обратите внимание, что я использовал visibility: hidden , вместо display: none . Вы не можете вызвать событие click для не отображаемого ввода файла.

Комментарии:

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

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

3. я просто попробовал click() display:none ввести, и это сработало

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

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

Ответ №2:

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

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

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

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

Комментарии:

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

2. вы можете щелкнуть что-то, что генерируется динамически. в jquery это $(staticElementParent).on("click", "dynamicChild", function(){})

3. Спасибо!!!! Я тестировал все эти ответы в консоли javascript и сходил с ума!

4. Я уже полчаса пытаюсь программно вызвать окно ввода файла. НИКТО БОЛЬШЕ не заявлял, что это невозможно, если событие не запускается пользователем… вы заслуживаете много 1.

5. Начиная с Chrome 62 debugger; ключевое слово больше не прерывает программный щелчок

Ответ №3:

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

Вам нужен a <label> с соответствующим for атрибутом (указывает на ввод), необязательно оформленный как кнопка (с помощью bootstrap, используйте 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" /> 

Комментарии:

1. Мне нравится этот, не хочу включать полный jQuery в мой проект Angular, работает хорошо 🙂

2. является ли это поведение надежным во всех современных браузерах?

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

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

Ответ №4:

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

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

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

Комментарии:

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

2. Знаете ли вы, как это можно протестировать с помощью Selenium, если ввода нет в DOM?

Ответ №5:

Я оборачиваю input[type=file] в тег label, затем оформляю 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-решение.

Комментарии:

1. Просто установите <input type="file" hidden> , чтобы удалить необходимость применения стиля CSS.

Ответ №6:

В настоящее время гибридное решение, подобное этому, может иметь наилучший опыт,

 let fileHandle;
async function fileOpen() {
    [fileHandle] = await window.showOpenFilePicker();
    const file = await fileHandle.getFile();
    console.log(await file.text());
}
// The advantage of this is fileHandle can be used to save to
// the opened file itself later, read more on this in https://web.dev/file-system-access/


// in April 2021, window.showOpenFilePicker still not support in Safari
// so one should have this around also
function legacyFileOpen() {
    var input = document.createElement('input');
    input.type = 'file';
    input.onchange = function () {
        input.files[0].arrayBuffer().then(function (arrayBuffer) {
            console.log(new TextDecoder().decode(arrayBuffer));
        });
    }
    input.click();
}
 

Ответ №7:

К сожалению, изначально единственный способ — создать <input type="file"> элемент, а затем имитировать щелчок.

Есть крошечный плагин (shameless plug), который избавит вас от необходимости делать это постоянно: 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
        })
    })
 

Ответ №8:

Лучшее решение, работает во всех браузерах.. даже на мобильном устройстве.

 <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.

2. Непрозрачность включает в себя совершенно не связанную концепцию — вам просто повезло, если это не повлияет на ваш макет с помощью «прозрачного» элемента. Элемент должен быть там, но не виден, поэтому visibility:hidden должен быть лучшим выбором.

3. visibility: hidden все еще влияет на макет. display: none это то, что вы хотите.

Ответ №9:

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

Комментарии:

1. О чем говорит OP <input type="file"> , а не <select> .

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

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

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

5. Хорошая исследовательская работа! Если бы я тратил копейки каждый раз, когда веб-разработчикам приходилось что-то делать с довольно нормальным поведением, я был бы неприлично богат.

Ответ №10:

Убедитесь, что вы используете привязку для получения реквизитов компонента в 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>)
  }
}
 

Ответ №11:

просмотр файла программно

 

function browseFile(accept) {
    const promise = resolvingPromise();
    const input = document.createElement('input');
    input.type = "file";
    input.accept = accept;
    input.onchange = function (e) {
        const files = e.target.files;
        promise.resolve(files);
    }
    setTimeout(function () {
        click(input);
    }, 0);
    return promise;
}

function click(node) {
    try {
        node.dispatchEvent(new MouseEvent('click'))
    } catch (e) {
        const evt = document.createEvent('MouseEvents')
        evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null)
        node.dispatchEvent(evt);
    }
}


 

Ответ №12:

Используя jQuery, вы можете вызвать click() для имитации щелчка.

Ответ №13:

Это сработало для меня:

 $('#fileInput').val('');
 

Ответ №14:

Для тех, кто хочет того же, но использует 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"/>
 

Ответ №15:

 <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>