Intereting Posts
Что такое viewport в HTML. Несколько форм с полями ввода с одним и тем же именем? Хорошо или плохо? В Pyramid, как мне вернуть необработанный HTML из представления? Символ Unicode (шестиугольник), не отображаемый на некоторых компьютерах Сохраняются ли данные формы, если входной тег не имеет имени? Отслеживание номера страницы в событии прокрутки Как запустить Java-код (.class) с помощью php и отображения на той же веб-странице Удаление маркеров в сервисах Google Maps Можно ли отобразить внутренний div с независимой таблицей стилей? Создание функций в JQuery, чтобы избежать написания того же кода Наложение CSS-перекрывающегося родительского элемента Обнаружить режим совместимости IE10 что такое определение цвета потолка и цвета подсветки в CSS? PhoneGap / Cordova открывает внешнюю ссылку в Safari вместо полного экрана inApp Ввод HTML-файла в веб-обозревателе Android (андроид 4.4, kitkat)

Как определить, когда нажатие на файл нажата на ввод файла?

Как определить, когда пользователь отменяет ввод файла с помощью ввода файла html?

onChange позволяет мне определять, когда они выбирают файл, но я также хотел бы знать, когда они отменяются (закройте диалог выбора файла, не выбирая ничего).

Хотя это не прямое решение, а также плохое в том, что только (насколько я проверял) работает с onfocus (требуется довольно ограничивающая блокировка событий), вы можете добиться этого следующим образом:

document.body.onfocus = function(){ /*rock it*/ } 

Что хорошо в этом, так это то, что вы можете присоединить / отсоединить его во времени с событием файла, и он также отлично работает со скрытыми входами (определенный перк, если вы используете визуальный обходной путь для дрянного ввода по умолчанию типа = файл’). После этого вам просто нужно выяснить, изменилось ли входное значение.

Пример:

 var godzilla = document.getElementById('godzilla') godzilla.onclick = charge function charge() { document.body.onfocus = roar console.log('chargin') } function roar() { if(godzilla.value.length) alert('ROAR! FILES!') else alert('*empty wheeze*') document.body.onfocus = null console.log('depleted') } 

См. Его в действии: http://jsfiddle.net/Shiboe/yuK3r/6/

К сожалению, он работает только в браузерах webkit. Возможно, кто-то еще может найти решение firefox / IE

Вы не можете.

Результат диалога с файлом не отображается в браузере.

 /* Tested on Google Chrome */ $("input[type=file]").bind("change", function() { var selected_file_name = $(this).val(); if ( selected_file_name.length > 0 ) { /* Some file selected */ } else { /* No file selected or cancel/close dialog button clicked */ /* If user has select a file before, when they submit, it will treated as no file selected */ } }); 

Когда вы выбираете файл и открываете / отменяете, элемент input должен терять фокус или blur . Предполагая, что начальное value input пуст, любое непустое значение в вашем обработчике blur указывает на ОК, а пустым значением будет «Отмена».

UPDATE: blur не запускается, когда input скрыт. Поэтому нельзя использовать этот трюк при загрузке на основе IFRAME, если вы не хотите временно отображать input .

Вы можете уловить отмену, если вы выберете тот же файл, что и ранее, и нажмите «Отмена»: в этом случае.

Вы можете сделать это следующим образом:

   

Просто слушайте событие click.

Следуя примеру Сибо, вот пример jQuery:

 var godzilla = $('#godzilla'); var godzillaBtn = $('#godzilla-btn'); godzillaBtn.on('click', function(){ godzilla.trigger('click'); }); godzilla.on('change click', function(){ if (godzilla.val() != '') { $('#state').html('You have chosen a Mech!'); } else { $('#state').html('Choose your Mech!'); } }); 

Вы можете увидеть это в действии здесь: http://jsfiddle.net/T3Vwz

Самый простой способ – проверить, есть ли файлы во временной памяти. Если вы хотите получить событие изменения каждый раз, когда пользователь нажимает на ввод файла, вы можете вызвать его.

 var yourFileInput = $("#yourFileInput"); yourFileInput.on('mouseup', function() { $(this).trigger("change"); }).on('change', function() { if (this.files.length) { //User chose a picture } else { //User clicked cancel } }); 

Решение Шибо было бы хорошим, если бы оно работало на мобильном веб-китке, но это не так. Я могу придумать, чтобы добавить слушателя событий mousemove к некоторому dom-объекту в то время, когда открывается окно ввода файла, например:

  $('.upload-progress').mousemove(function() { checkForFiles(this); }); checkForFiles = function(me) { var filefield = $('#myfileinput'); var files = filefield.get(0).files; if (files == undefined || files[0] == undefined) $(me).remove(); // user cancelled the upload }; 

Событие mousemove заблокировано со страницы, когда диалог файла открыт, и когда его закрытая проверяет, есть ли в файле файлы. В моем случае я хочу, чтобы индикатор активности блокировал вещи до тех пор, пока файл не будет загружен, поэтому я хочу только удалить свой индикатор при отмене.

Однако это не решает для мобильных устройств, поскольку мышь не перемещается. Мое решение там менее совершенное, но я считаю его достаточно хорошим.

  $('.upload-progress').bind('touchstart', function() { checkForFiles(this); }); 

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

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

Большинство из этих решений не работают для меня.

Проблема в том, что вы никогда не знаете, какое событие будет вызвано кулаком, click или change ? Вы не можете принять какой-либо заказ, потому что он, вероятно, зависит от реализации браузера.

По крайней мере, в Opera и Chrome (конец 2015 года) click запускается непосредственно перед «заполнением» ввода файлами, поэтому вы никогда не узнаете длину files.length != 0 до тех пор, пока вы не click который будет запущен после change .

Вот код:

 var inputfile = $("#yourid"); inputfile.on("change click", function(ev){ if (ev.originalEvent != null){ console.log("OK clicked"); } document.body.onfocus = function(){ document.body.onfocus = null; setTimeout(function(){ if (inputfile.val().length === 0) console.log("Cancel clicked"); }, 1000); }; }); 

Я знаю, что это очень старый вопрос, но на всякий случай это помогает кому-то, я обнаружил, что при использовании события onmousemove, чтобы обнаружить отмену, необходимо было провести тест на два или более таких события за короткий промежуток времени. Это связано с тем, что отдельные события onmousemove генерируются браузером (Chrome 65) каждый раз, когда курсор перемещается из диалогового windows выбора файла и каждый раз, когда он перемещается из главного windows и обратно. Простой счетчик событий перемещения мыши в сочетании с кратковременным таймаутом, чтобы сбросить счетчик обратно до нуля, обработало удовольствие.

В моем случае мне пришлось скрывать кнопку отправки, пока пользователи выбирали изображения.

Это то, что я придумал:

 $(document).on('click', '#image-field', function(e) { $('.submit-button').prop('disabled', true) }) $(document).on('focus', '#image-field'), function(e) { $('.submit-button').prop('disabled', false) }) 

#image-field – это мой файловый селектор. Когда somenone нажимает на него, я отключу кнопку отправки формы. Дело в том, что когда диалог с файлом закрыт – неважно, что они выбирают файл или отменяет – #image-field снова получил фокус, поэтому я слушаю это событие.

ОБНОВИТЬ

Я обнаружил, что это не работает в safari и полтергейсте / phantomjs. Учитывайте эту информацию, если вы хотите ее реализовать.

Сочетая решения Shiboe и alx, у меня самый надежный код:

 var selector = $('') .attr({ /* just for example, use your own attributes */ "id": "FilesSelector", "name": "File", "type": "file", "contentEditable": "false" /* if you "click" on input via label, this prevents IE7-8 from just setting caret into file input's text filed*/ }) .on("click.filesSelector", function () { /* do some magic here, eg invoke callback for selection begin */ var cancelled = false; /* need this because .one calls handler once for each event type */ setTimeout(function () { $(document).one("mousemove.filesSelector focusin.filesSelector", function () { /* namespace is optional */ if (selector.val().length === 0 && !cancelled) { cancelled = true; /* prevent double cancel */ /* that's the point of cancel, */ } }); }, 1); /* 1 is enough as we just need to delay until first available tick */ }) .on("change.filesSelector", function () { /* do some magic here, eg invoke callback for successful selection */ }) .appendTo(yourHolder).end(); /* just for example */ 

Как правило, событие mousemove делает трюк, но в случае, если пользователь сделал клик и чем:

  • отмененный диалог открытия файла с помощью клавиши перехода (без перемещения мыши), сделал еще один точный щелчок, чтобы снова открыть диалоговое окно файла …
  • переключил фокус на любое другое приложение, чем вернулся в диалоговое окно открытия файла браузера и закрыл его, а затем открыл снова с помощью клавиши ввода или пробела …

… мы не получим mousemove event, следовательно, не отменяем обратный вызов. Более того, если пользователь отменяет второй диалог и совершает движение мыши, мы получим 2 отмененных обратных вызова. К счастью, специальное событие jQuery focusIn в обоих случаях пузырится до документа, помогая нам избежать таких ситуаций. Единственным ограничением является то, что каждый из них блокирует событие focusIn.

Я вижу, что мой ответ будет довольно устаревшим, но тем не менее. Я столкнулся с той же проблемой. Итак, вот мое решение. Самый полезный код, отрезанный, был KGA. Но он не совсем работает и немного сложнее. Но я упростил это.

Кроме того, основным создателем проблем был тот факт, что событие «change» не приходит сразу после фокуса, поэтому нам нужно подождать некоторое время.

«#appendfile» – какой пользователь нажимает, чтобы добавить новый файл. Hrefs получают фокусные события.

 $("#appendfile").one("focusin", function () { // no matter - user uploaded file or canceled, // appendfile gets focus // change doesn't come instantly after focus, so we have to wait for some time // wrapper represents an element where a new file input is placed into setTimeout(function(){ if (wrapper.find("input.fileinput").val() != "") { // user has uploaded some file // add your logic for new file here } else { // user canceled file upload // you have to remove a fileinput element from DOM } }, 900); }); 

Вы можете обнаружить это только в ограниченных обстоятельствах. В частности, в chrome, если файл был выбран ранее, а затем щелкнуть диалог файла и отменить щелчок, Chrome очищает файл и запускает событие onChange.

https://code.google.com/p/chromium/issues/detail?id=2508

В этом случае вы можете обнаружить это, обработав событие onChange и проверив свойство файлов .

Кажется, что для меня работает (на рабочем столе, в windowsх):

 var openFile = function (mimeType, fileExtension) { var defer = $q.defer(); var uploadInput = document.createElement("input"); uploadInput.type = 'file'; uploadInput.accept = '.' + fileExtension + ',' + mimeType; var hasActivated = false; var hasChangedBeenCalled = false; var hasFocusBeenCalled = false; var focusCallback = function () { if (hasActivated) { hasFocusBeenCalled = true; document.removeEventListener('focus', focusCallback, true); setTimeout(function () { if (!hasChangedBeenCalled) { uploadInput.removeEventListener('change', changedCallback, true); defer.resolve(null); } }, 300); } }; var changedCallback = function () { uploadInput.removeEventListener('change', changedCallback, true); if (!hasFocusBeenCalled) { document.removeEventListener('focus', focusCallback, true); } hasChangedBeenCalled = true; if (uploadInput.files.length === 1) { //File picked var reader = new FileReader(); reader.onload = function (e) { defer.resolve(e.target.result); }; reader.readAsText(uploadInput.files[0]); } else { defer.resolve(null); } }; document.addEventListener('focus', focusCallback, true); //Detect cancel uploadInput.addEventListener('change', changedCallback, true); //Detect when a file is picked uploadInput.click(); hasActivated = true; return defer.promise; } 

Это использует angularjs $ q, но при необходимости вы можете заменить его любой другой структурой обещаний.

Протестировано на IE11, Edge, Chrome, Firefox, но, похоже, он не работает на Chrome на планшете Android, так как он не запускает событие Focus.

Поэтому я брошу свою шляпу в этот вопрос, так как я придумал новое решение. У меня есть Progressive Web App, которое позволяет пользователям снимать фотографии и видео и загружать их. Мы используем WebRTC, когда это возможно, но возвращаемся к сборщикам файлов HTML5 для устройств с меньшей поддержкой * cough Safari cough *. Если вы работаете специально на мобильном веб-приложении Android / iOS, которое использует собственную камеру для непосредственного захвата фотографий / видео, то это лучшее решение, с которым я столкнулся.

Суть этой проблемы в том, что когда страница загружается, file имеет значение null , но затем, когда пользователь открывает диалоговое окно и нажимает «Отмена», file по-прежнему остается null , следовательно, он не «менялся», поэтому «изменение» не происходит, событие запускается. Для настольных компьютеров это не так уж плохо, потому что большинство пользовательских интерфейсов рабочего стола не зависят от того, зная, когда вызывается отмена, но мобильные пользовательские интерфейсы, которые воспитывают камеру для захвата фото / видео, очень зависят от знания при нажатии на отмену.

Первоначально я использовал событие document.body.onfocus чтобы обнаружить, когда пользователь вернулся из сборщика файлов, и это сработало для большинства устройств, но iOS 11.3 сломал его, поскольку это событие не запускается.

концепция

Мое решение этого – * содрогнуться *, чтобы измерить время синхронизации процессора, чтобы определить, находится ли страница в настоящее время на переднем плане или в фоновом режиме. На мобильных устройствах время обработки предоставляется приложению, находящемуся на переднем плане. Когда камера видна, она будет красть процессорное время и лишить пользователя браузера. Все, что нам нужно сделать, это измерить, сколько времени будет выдано нашей странице, когда камера запускает наше доступное время, резко сократится. Когда камера отклоняется (либо отменяется, либо иным образом), наш ansible всплеск времени сохраняется.

Реализация

Мы можем измерить время процессора, используя setTimeout() чтобы вызвать обратный вызов в X миллисекундах, а затем измерить, сколько времени потребовалось для его фактического вызова. Браузер никогда не будет вызывать его точно после X миллисекунд, но если это разумно близко, мы должны быть на переднем плане. Если браузер находится очень далеко (более 10 раз медленнее, чем требуется), мы должны быть в фоновом режиме. Основная реализация этого заключается в следующем:

 function waitForCameraDismiss() { const REQUESTED_DELAY_MS = 25; const ALLOWED_MARGIN_OF_ERROR_MS = 25; const MAX_REASONABLE_DELAY_MS = REQUESTED_DELAY_MS + ALLOWED_MARGIN_OF_ERROR_MS; const MAX_TRIALS_TO_RECORD = 10; const triggerDelays = []; let lastTriggerTime = Date.now(); return new Promise((resolve) => { const evtTimer = () => { // Add the time since the last run const now = Date.now(); triggerDelays.push(now - lastTriggerTime); lastTriggerTime = now; // Wait until we have enough trials before interpreting them. if (triggerDelays.length < MAX_TRIALS_TO_RECORD) { window.setTimeout(evtTimer, REQUESTED_DELAY_MS); return; } // Only maintain the last few event delays as trials so as not // to penalize a long time in the camera and to avoid exploding // memory. if (triggerDelays.length > MAX_TRIALS_TO_RECORD) { triggerDelays.shift(); } // Compute the average of all trials. If it is outside the // acceptable margin of error, then the user must have the // camera open. If it is within the margin of error, then the // user must have dismissed the camera and returned to the page. const averageDelay = triggerDelays.reduce((l, r) => l + r) / triggerDelays.length if (averageDelay < MAX_REASONABLE_DELAY_MS) { // Beyond any reasonable doubt, the user has returned from the // camera resolve(); } else { // Probably not returned from camera, run another trial. window.setTimeout(evtTimer, REQUESTED_DELAY_MS); } }; window.setTimeout(evtTimer, REQUESTED_DELAY_MS); }); } 

Я протестировал это в последней версии iOS и Android, создав собственную камеру, установив атрибуты в элементе .

   

Это на самом деле намного лучше, чем я ожидал. Он запускает 10 проб, запрашивая таймер, который вызывается в 25 миллисекунд. Затем он измеряет, сколько времени на самом деле требуется для вызова, и если в среднем 10 испытаний составляет менее 50 миллисекунд, мы предполагаем, что мы должны быть на переднем плане, и камера исчезла. Если это больше 50 миллисекунд, мы все равно должны быть в фоновом режиме и должны продолжать ждать.

Дополнительные сведения

Я использовал setTimeout() а не setInterval() потому что последний может ставить в очередь несколько вызовов, которые выполняются сразу после друг друга. Это может значительно увеличить шум в наших данных, поэтому я придерживался setTimeout() хотя это немного сложнее сделать.

Эти конкретные номера хорошо работали для меня, хотя я видел, по крайней мере, один раз экземпляр, где увольнение камеры было обнаружено преждевременно. Я считаю, что это связано с тем, что камера может медленно открываться, и устройство может запускать 10 испытаний, прежде чем они начнут происходить. Добавление большего количества проб или ожиданий в течение 25-50 миллисекунд перед началом этой функции может быть обходным путем для этого.

рабочий стол

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

Альтернативные решения

Одно из альтернативных решений, о которых многие люди не упоминают, я исследовал, издеваясь над FileList . Мы начинаем с null в а затем, если пользователь открывает камеру и отменяет, они возвращаются к null , что не является изменением, и никакое событие не будет срабатывать. Одним из решений было бы назначить фиктивный файл для при запуске страницы, поэтому установка в значение null будет изменением, которое вызовет соответствующее событие.

К сожалению, нет никакого официального способа создания FileList , а элемент требует, в частности, FileList и не примет никакое другое значение, кроме null . Естественно, объекты FileList не могут быть сконструированы напрямую, по какой-то старой проблеме безопасности, которая, по-видимому, даже не актуальна. Единственный способ получить элемент за пределами элемента - использовать хак, который копирует данные для фальсификации события буфера обмена, который может содержать объект FileList (вы в основном подталкиваете drag-and-drop- событие a-file-on-your-website). Это возможно в Firefox, но не для iOS Safari, поэтому это не было жизнеспособно для моего конкретного случая использования.

Браузеры, пожалуйста ...

Излишне говорить, что это явно смешно. Тот факт, что веб-страницам присваивается нулевое уведомление о том, что элемент критического элемента интерфейса изменился, просто смешно. Это действительно ошибка в спецификации, поскольку она никогда не предназначалась для полноэкранного пользовательского интерфейса захвата мультимедиа, а не для запуска события «изменения» технически для спецификации.

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

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

Существует хакерский способ сделать это (добавьте обратные вызовы или разрешите выполнение отложенных / обещаний вместо вызовов alert() ):

 var result = null; $('') .on('change', function () { result = this.files[0]; alert('selected!'); }) .click(); setTimeout(function () { $(document).one('mousemove', function () { if (!result) { alert('cancelled'); } }); }, 1000); 

Как это работает: в то время как диалог выбора файла открыт, документ не принимает события указателя мыши. Существует задержка в 1000 мс, чтобы диалоговое окно действительно отображалось и блокировало окно браузера. Проверено в Chrome и Firefox (только для Windows).

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

Вот мое решение, используя фокус ввода файла (не используя таймеры)

 var fileInputSelectionInitiated = false; function fileInputAnimationStart() { fileInputSelectionInitiated = true; if (!$("#image-selector-area-icon").hasClass("fa-spin")) $("#image-selector-area-icon").addClass("fa-spin"); if (!$("#image-selector-button-icon").hasClass("fa-spin")) $("#image-selector-button-icon").addClass("fa-spin"); } function fileInputAnimationStop() { fileInputSelectionInitiated = false; if ($("#image-selector-area-icon").hasClass("fa-spin")) $("#image-selector-area-icon").removeClass("fa-spin"); if ($("#image-selector-button-icon").hasClass("fa-spin")) $("#image-selector-button-icon").removeClass("fa-spin"); } $("#image-selector-area-wrapper").click(function (e) { $("#fileinput").focus(); $("#fileinput").click(); }); $("#preview-image-wrapper").click(function (e) { $("#fileinput").focus(); $("#fileinput").click(); }); $("#fileinput").click(function (e) { fileInputAnimationStart(); }); $("#fileinput").focus(function (e) { fileInputAnimationStop(); }); $("#fileinput").change(function(e) { // ... } 

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

В основном скройте « Continue , « Save , « Proceed или любую вашу кнопку. Затем в JavaScript вы получите имя файла. Если имя файла не имеет значения, не показывайте кнопку « Continue . Если у него есть значение, тогда покажите кнопку. Это также работает, если они сначала загружают файл, а затем пытаются загрузить другой файл и нажмите «Отменить».

Вот код.

HTML:

 

JavaScript:

 $('#fileUpload').change(function () { var fileName = $('#fileUpload').val(); if (fileName != "") { $('#file-upload-btn').html(fileName); $('#accept-btn').removeClass('hidden').addClass('show'); } else { $('#file-upload-btn').html("Upload File"); $('#accept-btn').addClass('hidden'); } }); 

CSS:

 .file-input { width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1; } .file-input + label { font-size: 1.25em; font-weight: normal; color: white; background-color: blue; display: inline-block; padding: 5px; } .file-input:focus + label, .file-input + label:hover { background-color: red; } .file-input + label { cursor: pointer; } .file-input + label * { pointer-events: none; } 

Для CSS это очень важно, чтобы сайт и кнопка были доступны для всех. Настройте свою кнопку так, как вам нравится.

Поле типа file , к сожалению, не отвечает на множество событий (размытие было бы прекрасным). Я вижу много людей, предлагающих change ориентированные на change и их снижение.

change действительно работает, но у него есть главный недостаток (по сравнению с тем, что мы хотим ).

Когда вы только что загрузите страницу, содержащую поле файла, откройте окно и нажмите «Отмена». Ничего, разочаровывающе, не меняется .

То, что я выбрал, – это загрузка в закрытом состоянии.

  • Следующая часть формы section#after-image в моем случае скрыта от представления. Когда мое file field изменяется, отображается кнопка загрузки. При успешной загрузке отображается section#after-image .
  • Если пользователь загружается, открывается диалоговое окно с файлом, а затем отменяется, они никогда не видят кнопку загрузки.
  • Если пользователь выбирает файл, отображается кнопка загрузки. Если они откроют диалоговое окно и отменит это событие, это событие отменяется, и я могу (и делать) снова скрывать мою кнопку загрузки до тех пор, пока не будет выбран правильный файл.

Мне повезло, что это закрытое государство уже было оформлением моей формы. Вам не нужно использовать один и тот же стиль, просто нажав кнопку загрузки и сменив ее, установив скрытое поле или переменную javascript на то, что вы можете отслеживать при отправке.

Я попытался изменить значение файлов [0], прежде чем поле было взаимодействовать. Это ничего не делало в отношении обмена.

Так что да, change работу, по крайней мере, так хорошо, как мы собираемся получить. Файловое поле защищено по понятным причинам, но к разочарованию благих намерений разработчиков.

Это не подходит для моей цели, но вы можете, onclick , загрузить предупреждение (а не alert() , потому что это останавливает обработку страниц) и скрыть его, если смена инициирована, а файлы [0] – null. Если изменение не запускается, div остается в своем состоянии.

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

Если это так, то: Зачем добавлять пустые входные данные?

Создайте один на лету, но добавьте его в DOM только после его заполнения. Например:

  var fileInput = $(""); fileInput.bind("change", function() { if (fileInput.val() !== null) { // if has value add it to DOM $("#files").append(fileInput); } }).click(); 

Поэтому здесь я создаю на лету, привязываюсь к его событию изменения, а затем сразу же вызываю клик. При изменении будет срабатывать только при выборе пользователем файла и нажатии «ОК», иначе вход не будет добавлен в DOM, поэтому он не будет отправлен.

Рабочий пример: https://jsfiddle.net/69g0Lxno/3/

// Использовать зависание вместо размытия

 var fileInput = $("#fileInput"); if (fileInput.is(":hover") { //open } else { } 
 function file_click() { document.body.onfocus = () => { setTimeout(_=>{ let file_input = document.getElementById('file_input'); if (!file_input.value) alert('please choose file ') else alert(file_input.value) document.body.onfocus = null },100) } } 

Using setTimeout to get the certain value of the input.

I found this atribute, its most simple yet.

 if ($('#selectedFile')[0].files.length > 1) { // Clicked on 'open' with file } else { // Clicked on 'cancel' } 

Here, selectedFile is an input type=file .

You can make a jquery change listener on the input field and detect that user cancel or closed upload window by the value of the field.

here is an example:

 //when upload button change $('#upload_btn').change(function(){ //get uploaded file var file = this.files[0]; //if user choosed a file if(file){ //upload file or perform your desired functiuonality }else{ //user click cancel or close the upload window } }); 

I needed to do it and I ended up creating a very simple solution. Can be seen here: http://jsfiddle.net/elizeubh2006/1w711q0y/5/

(But will only work after a first file selection has occurred. For me it was useful because the onchange event was being called even when the user clicked cancel. The user chose a file, then clicked to select another file, but canceled and the onchange was called.)

  $("#inputFileId").on("change", function() { var x = document.getElementById('inputFileId'); if(x.files.length == 0) { alert('cancel was pressed'); } else { alert(x.files[0].name); } }); 

input type=file code:

 onchange="if(this.files[0]!=undefined){ UploadImg(); }else{ alert('cancel'); }"