#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/12. Знаете ли вы, как это можно протестировать с помощью 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>