Я хотел бы программно запустить событие щелчка для тега <input type = "file">.
Кажется, что простой вызов click () ничего не делает или, по крайней мере, не вызывает диалоговое окно выбора файла.
Я экспериментировал с захватом событий с помощью слушателей и перенаправлением события, но мне не удалось заставить это фактически выполнить событие, как будто кто-то щелкнул по нему.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не можете сделать это во всех браузерах, предположительно IE делает разрешает это, но Mozilla и Opera этого не делают.
Когда вы составляете сообщение в GMail, функция «прикреплять файлы» реализуется одним способом для IE и любого браузера, который поддерживает это, а затем реализуется другим способом для Firefox и тех браузеров, которые этого не делают.
Я не знаю, почему вы не можете этого сделать, но одна вещь, которая является представляет угрозу безопасности и которую вам не разрешено делать в любом браузере, - это программная установка имени файла в элементе HTML File.
Драт. Я, конечно, понимаю, что это можно использовать. Это где-нибудь задокументировано? Я предполагаю, что это будет реализовано каждым браузером?
Обновил мой ответ, чтобы он был более правильным, чем предыдущий ответ - суть такая же, но разъяснения должны немного помочь. Этот парень столкнулся с той же проблемой: bytes.com/forum/thread542877.html
Слава Богу, FF5 позволяет этот щелчок
Да, но Chrome, похоже, не поддерживает click () :(
Chrome сделал принимает click () и открывает диалоговое окно (мы использовали его несколько месяцев) до самой последней стабильной версии Chrome. :(
Чтобы прояснить комментарий выше: Chrome недавно изменил, чтобы проверить, виден ли элемент файла input. Запуск метода click работает, в том числе и в консоли, если элемент виден.
Теперь работает и в Chrome, когда он невидим. Нет, если это в iframe.
в FF это работает, я давно пользуюсь этим трюком, и он работает. Небольшой совет: не используйте click (), потому что этот дерьмовый метод унаследован от IE и не работает, я всегда использую new MouseEvent / dispatchEvent
Ребята, это неправильный ответ. Да, ты можешь сделать это. Я добавил еще один ответ со ссылкой на очень короткую статью. Мой ответ на самом деле находится в самом конце этого длинного списка неясных объяснений. Что ж, иногда жизнь сурова с правильными и правдивыми ответами.
@Otvazhnii - чувак, этому ответу (тот, который ты говоришь неверен) 10 лет - неудивительно, что это неверно! (Точно не знаю, верю вам на слово). :П
Есть способы перенаправить события в элемент управления, но не ожидайте, что сможете легко запускать события в элемент управления огнем, поскольку браузеры попытаются заблокировать это по (хорошим) соображениям безопасности.
Если вам нужно, чтобы диалоговое окно файла отображалось только тогда, когда пользователь что-то нажимает, скажем, потому что вам нужны более привлекательные кнопки загрузки файлов, тогда вы можете взглянуть на что придумал Шон Инман.
Мне удалось добиться срабатывания клавиатуры с творческим переключением фокуса между событиями keydown, keypress и keyup. YMMV.
Мой искренний совет - оставить это в покое, потому что это мир проблем несовместимости браузеров. Незначительные обновления браузера также могут блокировать уловки без предупреждения, и вам, возможно, придется изобретать новые хаки, чтобы он работал.
Я исследовал это некоторое время назад, потому что хотел создать настраиваемую кнопку, которая открывала бы диалоговое окно файла и немедленно начинала загрузку. Я только что заметил кое-что, что может сделать это возможным - firefox, кажется, открывает диалоговое окно, когда вы щелкаете в любом месте загрузки. Таким образом, это может сделать следующее:
Это только теоретически, поскольку я уже использовал другой метод для решения проблемы, но он может сработать.
Я весь день искал решение. И вот выводы, которые я сделал:
Надеюсь это поможет! :)
<div style = "display: block; width: 100px; height: 20px; overflow: hidden;">
<button style = "width: 110px; height: 30px; position: relative; top: -5px; left: -5px;"><a href = "javascript: void(0)">Upload File</a></button>
<input type = "file" id = "upload_input" name = "upload" style = "font-size: 50px; width: 120px; opacity: 0; filter:alpha(opacity=0); position: relative; top: -40px;; left: -20px" />
</div>
это решение отлично работает. Не уверен, почему его не заметили и не переоценили. Это не совсем то, о чем спрашивает вопрос, но это отличная работа. Вы обнаружили, что он несовместим с какими-либо браузерами? У меня нет времени пробираться через все 10+ подходящих вариантов для тестирования.
Спасибо за такой ответ, это круто: D
Хорошее решение. Работает и в мобильном браузере Android.
Спасибо за это! Мы использовали аналогичный подход, но он не работал правильно в IE ... Внешний div overflow: hidden; и входные стили font-size: 50px; заставляют его работать для меня!
спасибо сработало для меня 2, вы можете скрыть ввод файла, обернув его шириной / высотой div = 0/0 и скрытым переполнением.
Это неправда, см. Ответ Дидье ниже. Программный щелчок должен происходить из контекста действия пользователя - как в обработчике щелчка другой кнопки. Тогда он работает нормально, нет необходимости в элементе переполнения.
Небольшая опечатка в стиле ввода: это должен быть filter:alpha(opacity=0);.
К сожалению, это не работает при использовании элемента button.
Хороший водный трюк, мой друг. Я использовал компонент загрузки файлов Primefaces, спрятанный в каком-то темном углу страницы, потому что внешний вид по умолчанию выглядел просто ужасно на нашей странице портала, и я щелкал загрузку файла с помощью пиктограммы, которая выглядит как часть стандартного стиля. Прекрасно работает в IE и Firefox (более старая версия из-за драйвера селена). А вот на хроме шансов нет. jquery (). click () не открылся. Ваше предложение просто идеально. огромное спасибо.
Единственная проблема, с которой я столкнулся, заключалась в том, что когда ввод изменился, по какой-то причине он снова стал видимым (о, IE7 ...), поэтому я просто обернул ввод в другой div и вместо этого сделал прозрачный объект, работающий как шарм
кто, черт возьми, до сих пор пользуется IE7?
Единственная проблема заключается в том, что если вы хотите изменить стиль кнопки при наведении курсора, вы не сможете. Это означает, что если вы хотите, чтобы она выглядела как все остальные кнопки в вашем приложении, вы не можете.
Для тех, кто понимает, что надо накладывать невидимую форму поверх ссылки, но лень писать, я написал для вас. Что ж, для меня, но с таким же успехом можно поделиться. Комментарии приветствуются.
HTML (где-то):
<a id = "fileLink" href = "javascript:fileBrowse();" onmouseover = "fileMove();">File Browse</a>
HTML (где-то вас не волнует):
<div id = "uploadForm" style = "filter:alpha(opacity=0); opacity: 0.0; width: 300px; cursor: pointer;">
<form method = "POST" enctype = "multipart/form-data">
<input type = "file" name = "file" />
</form>
</div>
JavaScript:
function pageY(el) {
var ot = 0;
while (el && el.offsetParent != el) {
ot += el.offsetTop ? el.offsetTop : 0;
el = el.offsetParent;
}
return ot;
}
function pageX(el) {
var ol = 0;
while (el && el.offsetParent != el) {
ol += el.offsetLeft ? el.offsetLeft : 0;
el = el.offsetParent;
}
return ol;
}
function fileMove() {
if (navigator.appName == "Microsoft Internet Explorer") {
return; // Don't need to do this in IE.
}
var link = document.getElementById("fileLink");
var form = document.getElementById("uploadForm");
var x = pageX(link);
var y = pageY(link);
form.style.position = 'absolute';
form.style.left = x + 'px';
form.style.top = y + 'px';
}
function fileBrowse() {
// This works in IE only. Doesn't do jack in FF. :(
var browseField = document.getElementById("uploadForm").file;
browseField.click();
}
Попробуйте это решение: http://code.google.com/p/upload-at-click/
Это выглядит очень некрасиво, по крайней мере, в IE9.
Теперь это будет возможно в Firefox 4 с оговоркой, что оно считается всплывающим окном и поэтому будет блокироваться всякий раз, когда всплывающее окно могло появиться.
На самом деле firefox4 значительно улучшает состояние загрузки файлов. Моя проблема в том, как сделать то же самое в браузере Google Chrome.
Вы можете запустить click () в любом браузере, но некоторым браузерам нужно, чтобы элемент был видимым и сфокусированным. Вот пример jQuery:
$('#input_element').show();
$('#input_element').focus();
$('#input_element').click();
$('#input_element').hide();
Он работает с hide до click(), но я не знаю, работает ли он без вызова метода show. Никогда не пробовал это в Opera, я тестировал в IE / FF / Safari / Chrome, и он работает. Я надеюсь, это поможет.
Спасибо, что поделился. На всякий случай, если вы не знали - вы можете использовать цепочку в jQuery: $(...).show().focus().click().hide(); :)
@pimvdb: насколько я знаю, ваше решение работает только в Chrome.
@ Hoàng Long: Вы имеете в виду цепочку или решение Флорина Могоса? Я не верю, что создание цепочек повлияет на кроссбраузерность.
@pimvdb: Я имею в виду решение Флорина.
@ HoàngLong У меня работает в IE 8 и 9, последних версиях Chrome, Safari и Firefox.
Странный. Как я тестировал, он не работает в Chrome в Ubuntu.
Для меня это не работает в Firefox, хотя IE работает нормально. У меня нет других браузеров для тестирования.
Работает в браузере Android для версии Android 4.0.4, а также iOS 8.0.2
Прекрасно работает. Установите элемент входного файла на opacity: 0 и position: absolute, чтобы он не отображался при нажатии в IE, в противном случае он, кажется, работает везде нормально.
Чтобы добавить к моему предыдущему комментарию (поскольку я не могу его редактировать): установите для него значение width: 0px; в дополнение к свойствам непрозрачности и положения, чтобы полностью избежать случайных рывков в IE.
Нет, это не работает. И если он работает, это может быть из-за версии браузера. В Chrome версии 47.0.2526.106 m, похоже, нет способа получить команду загрузки файла Primefaces, чтобы открыть всплывающее окно с файлом.
Было здорово! Но, к сожалению, в настоящее время это не работает в современном браузере!
Этот код у меня работает. Это то, что вы пытаетесь сделать?
<input type = "file" style = "position:absolute;left:-999px;" id = "fileinput" />
<button id = "addfiles" >Add files</button>
<script language = "javascript" type = "text/javascript">
$("#addfiles").click(function(){
$("#fileinput").click();
});
</script>
Вот решение, которое работает для меня: CSS:
#uploadtruefield {
left: 225px;
opacity: 0;
position: absolute;
right: 0;
top: 266px;
opacity:0;
-moz-opacity:0;
filter:alpha(opacity:0);
width: 270px;
z-index: 2;
}
.uploadmask {
background:url(../img/browse.gif) no-repeat 100% 50%;
}
#uploadmaskfield{
width:132px;
}
HTML с "маленькой" справкой JQuery:
<div class = "uploadmask">
<input id = "uploadmaskfield" type = "text" name = "uploadmaskfield">
</div>
<input id = "uploadtruefield" type = "file" onchange = "$('#uploadmaskfield').val(this.value)" >
Просто убедитесь, что maskfied полностью закрывается истинным полем загрузки.
У меня был скрыт тег <input type = "button">. Я прикрепил событие "onClick" к любому видимому компоненту любого типа, например, к метке. Это было сделано с помощью инструментов разработчика Google Chrome или Firebug Mozilla Firefox с помощью команды «редактировать HTML», щелкнув правой кнопкой мыши. В этом случае укажите следующий сценарий или что-то подобное:
Если у вас есть JQuery:
$('#id_of_component').click();
если не:
document.getElementById('id_of_component').click();
Спасибо.
Если вы хотите, чтобы метод click работал в Chrome, Firefox и т. д., Примените к входному файлу следующий стиль. Он будет отлично спрятан, как будто у вас display: none;
#fileInput {
visibility: hidden;
position: absolute;
top: 0;
left: -5000px;
}
Это так просто, я тестировал, работает!
Мне этот способ нравится больше всего, поскольку некоторые старые браузеры ничего не делают с inputElement.click (), если он скрыт.
Почему бы просто не установить height и width на 0?
ЭТО ВОЗМОЖНО: В FF4 +, Opera?, Chrome: но:
inputElement.click() следует вызывать из контекста действий пользователя! (не контекст выполнения скрипта)
<input type = "file" /> должен быть видимым (inputElement.style.display !== 'none') (вы можете скрыть его с помощью видимости или чего-то другого, но не свойством "display")
Это решило проблему для меня. Мне пришлось добавить javascript в атрибут onclick вместо привязки к событию.
Голосование за единственное разумное решение. Метод переполнения уродлив.
Ха! Я знал, что это должно быть связано с контекстом! Я заметил, что вызов inputElement.click() из события нажатия клавиши (ярлык для прикрепления файла) работал, но вызов его по таймауту или обратному вызову ajax НЕ работал. Проголосовали.
Кстати, есть ли у кого-нибудь дополнительные ресурсы по «контексту действий пользователя» по сравнению с «контекстом выполнения скрипта»? Все, что я вижу при поиске, связано с контекстом выполнения и this. : /
@bretjonesdev Я думаю, это означает, что он должен выполняться внутри обработчика событий, инициированного пользователем, такого как обработчик события щелчка, в отличие от обещания, тайм-аута или любого другого события, не инициированного пользователем.
Мое решение для Safari с jQuery и jQuery-ui:
$("<input type='file' class='ui-helper-hidden-accessible' />").appendTo("body").focus().trigger('click');
Heads up: не работает для firefox 33, chrome 38. триггер («щелчок») может работать только в контексте событий взаимодействия с пользователем - обработчиках событий.
$(document).one('mousemove', function() { $(element).trigger('click') } );
У меня сработало, когда я столкнулся с подобной проблемой, это обычный eRube Goldberg.
WORKING SOLUTION
Позвольте мне добавить к этому старому посту рабочее решение, которое я использовал, которое работает, вероятно, в 80% или более всех браузеров, как новых, так и старых.
Решение сложное, но простое. Первый шаг - использовать CSS и замаскировать тип входного файла с «нижними элементами», которые видны, поскольку он имеет непрозрачность 0. Следующим шагом является использование JavaScript для обновления его метки по мере необходимости.
HTMLThe ID's are simply inserted if you wanted a quick way to access a specific element, the classes however, are a must as they relate to the CSS that sets this whole process up
<div class = "file-input wrapper">
<input id = "inpFile0" type = "file" class = "file-input control" />
<div class = "file-input content">
<label id = "inpFileOutput0" for = "inpFileButton" class = "file-input output">Click Here</label>
<input id = "inpFileButton0" type = "button" class = "file-input button" value = "Select File" />
</div>
</div>
CSS Keep in mind, coloring and font-styles and such are totally your preference, if you use this basic CSS, you can always use after-end mark up to style as you please, this is shown in the jsFiddle listed at the end.
.file-test-area {
border: 1px solid;
margin: .5em;
padding: 1em;
}
.file-input {
cursor: pointer !important;
}
.file-input * {
cursor: pointer !important;
display: inline-block;
}
.file-input.wrapper {
display: inline-block;
font-size: 14px;
height: auto;
overflow: hidden;
position: relative;
width: auto;
}
.file-input.control {
-moz-opacity:0 ;
filter:alpha(opacity: 0);
opacity: 0;
height: 100%;
position: absolute;
text-align: right;
width: 100%;
z-index: 2;
}
.file-input.content {
position: relative;
top: 0px;
left: 0px;
z-index: 1;
}
.file-input.output {
background-color: #FFC;
font-size: .8em;
padding: .2em .2em .2em .4em;
text-align: center;
width: 10em;
}
.file-input.button {
border: none;
font-weight: bold;
margin-left: .25em;
padding: 0 .25em;
}
JavaScriptPure and true, however, some OLDER (retired) browsers may still have trouble with it (like Netscrape 2!)
var inp = document.getElementsByTagName('input');
for (var i=0;i<inp.length;i++) {
if (inp[i].type != 'file') continue;
inp[i].relatedElement = inp[i].parentNode.getElementsByTagName('label')[0];
inp[i].onchange /*= inp[i].onmouseout*/ = function () {
this.relatedElement.innerHTML = this.value;
};
};
Вы можете сделать это согласно ответу Диалоговое окно открытия файла для тега <a>
<input type = "file" id = "upload" name = "upload" style = "visibility: hidden; width: 1px; height: 1px" multiple />
<a href = "" onclick = "document.getElementById('upload').click(); return false">Upload</a>
Я обнаружил, что если input (файл) находится вне формы, то запуск события щелчка вызывает диалоговое окно файла.
Надеюсь, это кому-то поможет - я потратил 2 часа на то, чтобы биться об него головой:
В IE8 или IE9, если вы каким-либо образом инициируете открытие ввода файла с помощью javascript (поверьте, я пробовал их все), он не позволит вам отправить форму с помощью javascript, он просто потерпит неудачу.
Отправка формы с помощью обычной кнопки отправки может работать, но вызов form.submit (); молча потерпит неудачу.
Мне пришлось прибегнуть к наложению моей кнопки выбора файла с прозрачным вводом файла, который работает.
Кроме того, вы можете обернуть ввод файла в метку, чтобы в IE вы могли получить интерактивную область метки, покрывающую всю область вашей кнопки, тогда как с помощью только тега ввода файла в IE можно щелкнуть только половину.
Оно работает :
По соображениям безопасности в Firefox и Opera вы не можете активировать щелчок при вводе файла, но вы можете моделировать с помощью MouseEvents:
<script>
click=function(element){
if (element!=null){
try {element.click();}
catch(e) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);
element.dispatchEvent(evt);
}
}
};
</script>
<input type = "button" value = "upload" onclick = "click(document.getElementById('inputFile'));"><input type = "file" id = "inputFile" style = "display:none">
Обратите внимание, что createEvent() и initMouseEvent() теперь не рекомендуются.
Это сработало для меня:
<script>
function sel_file() {
$("input[name=userfile]").trigger('click');
}
</script>
<input type = "file" name = "userfile" id = "userfile" />
<a href = "javascript:sel_file();">Click</a>
Я знаю, что это устарело, и все эти решения представляют собой реальную ценность взломов мер безопасности браузера.
Тем не менее, на сегодняшний день fileInput.click () работает в текущем Chrome (36.0.1985.125 м) и текущем Firefox ESR (24.7.0), но не в текущем IE (11.0.9600.17207). Наложение поля файла с непрозрачностью 0 поверх кнопки работает, но мне нужен элемент ссылки в качестве видимого триггера, а подчеркивание при наведении не работает ни в одном браузере. Он мигает, а затем исчезает, вероятно, браузер думает, действительно ли применяется стиль наведения или нет.
Но я нашел решение, которое работает во всех этих браузерах. Я не буду утверждать, что тестировал каждую версию каждого браузера или что я знаю, что он будет работать вечно, но, похоже, теперь он отвечает моим потребностям.
Это просто: поместите поле ввода файла за пределы экрана (position: absolute; top: -5000px), поместите вокруг него элемент метки и активируйте щелчок по метке вместо самого поля файла.
Обратите внимание, что ссылка должна быть написана в сценарии для вызова метода щелчка метки, это не происходит автоматически, например, когда вы щелкаете текст внутри элемента метки. Очевидно, элемент ссылки фиксирует щелчок и не доходит до метки.
Также обратите внимание, что это не дает возможности показать текущий выбранный файл, поскольку поле находится за пределами экрана. Я хотел отправить сразу же после выбора файла, так что для меня это не проблема, но вам понадобится несколько другой подход, если ваша ситуация другая.
Хорошо, в теге кнопки onclick = "filetag.click ()" не работает с IE 9 и 10 (но работает с IE 11, Firefox 4/10/26/27/28, Chrome / Chromium 31/32/33 / 36, Safari 7, Opera 23). Но если вы используете метку для = "id-of-file-input" (без onlick), она работает в IE 9/10/11.
просто используйте тег метки, таким образом вы можете скрыть ввод и заставить его работать через связанную метку https://developer.mozilla.org/fr/docs/Web/HTML/Element/Label
Это правильный ответ, и его следует продвигать.
Это правильный ответ. Все остальные - долгие и болезненные взломы.
JS Fiddle: http://jsfiddle.net/eyedean/1bw357kw/
popFileSelector = function() {
var el = document.getElementById("fileElem");
if (el) {
el.click();
}
};
window.popRightAway = function() {
document.getElementById('log').innerHTML += 'I am right away!<br />';
popFileSelector();
};
window.popWithDelay = function() {
document.getElementById('log').innerHTML += 'I am gonna delay!<br />';
window.setTimeout(function() {
document.getElementById('log').innerHTML += 'I was delayed!<br />';
popFileSelector();
}, 1000);
};<body>
<form>
<input type = "file" id = "fileElem" multiple accept = "image/*" style = "display:none" onchange = "handleFiles(this.files)" />
</form>
<a onclick = "popRightAway()" href = "#">Pop Now</a>
<br />
<a onclick = "popWithDelay()" href = "#">Pop With 1 Second Delay</a>
<div id = "log">Log: <br /></div>
</body>это не невозможно:
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
setTimeout(function(){ document.getElementById('input_field_id').dispatchEvent(evObj); },100);
Но каким-то образом это работает, только если это функция, которая была вызвана через событие щелчка.
Итак, у вас может быть следующая настройка:
html:
<div onclick = "openFileChooser()" class = "some_fancy_stuff">Click here to open image chooser</div>
<input type = "file" id = "input_img">
JavaScript:
function openFileChooser() {
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
setTimeout(function()
{
document.getElementById('input_img').dispatchEvent(evObj);
},100);
}
createEvent() и initMouseEvent() устарели. Вы должны использовать CustomEvent() сейчас ...
Вот чистое решение этой проблемы на JavaScript. Хорошо работает во всех браузерах
<script>
function upload_image_init(){
var elem = document.getElementById('file');
if (elem && document.createEvent) {
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, false);
elem.dispatchEvent(evt);
}
}
</script>
Вы можете использовать
<button id = "file">select file</button>
<input type = "file" name = "file" id = "file_input" style = "display:none;">
<script>
$('#file').click(function() {
$('#file_input').focus().trigger('click');
});
</script>
Привет, это решение работает. для загрузки мы должны использовать MSBLOB
$scope.getSingleInvoicePDF = function(invoiceNumberEntity) {
var fileName = invoiceNumberEntity + ".pdf";
var pdfDownload = document.createElement("a");
document.body.appendChild(pdfDownload);
AngularWebService.getFileWithSuffix("ezbillpdfget",invoiceNumberEntity,"pdf" ).then(function(returnedJSON) {
var fileBlob = new Blob([returnedJSON.data], {type: 'application/pdf'});
if (navigator.appVersion.toString().indexOf('.NET') > 0) { // for IE browser
window.navigator.msSaveBlob(fileBlob, fileName);
} else { // for other browsers
var fileURL = window.URL.createObjectURL(fileBlob);
pdfDownload.href = fileURL;
pdfDownload.download = fileName;
pdfDownload.click();
}
});
};
Для AngularJS или даже для обычного javascript.
Событие щелчка, которое вы запускаете, должно вызываться в событии щелчка, запущенном пользователем, иначе оно не сработает.