Загрузка файлов с использованием поля input type="file" с событием .change() не всегда срабатывает в IE и Chrome
У меня есть простой кусок кода для загрузки файлов:
$(document).ready(function () {
$(".attachmentsUpload input.file").change(function () {
$('form').submit();
});
});
<form class="attachmentsUpload" action="/UploadHandler.ashx" method="post" enctype="multipart/form-data">
<input type="file" class="file" name="file" />
</form>
Пока я нажимаю на ввод, а затем выбираю файл в диалоговом окне, я отправляю этот файл с помощью ajax. Это не важная часть здесь. Важная часть состоит в том, что, когда я дважды выбираю тот же файл в диалоговом окне, сразу после отправки первого файла, событие .change() не срабатывает в IE и Chrome. Но, когда я выбираю другой файл, событие срабатывает и работает правильно. Под Firefox он все время стреляет.
Как обойти это, работать как ожидалось (как в Firefox)?
Ответы
Ответ 1
Описание
Это происходит потому, что значение поля ввода (выбранный путь к файлу) не изменяется, если вы снова выбираете тот же файл.
Вы можете установить значение в событии onChange()
пустой строкой и отправить свою форму, только если значение не пустое. Посмотрите на мой образец и демонстрация jsFiddle.
Пример
$(".attachmentsUpload input.file").change(function () {
if ($(".attachmentsUpload input.file").val() == "") {
return;
}
// your ajax submit
$(".attachmentsUpload input.file").val("");
});
Update
Это по какой-либо причине не работает в IE9. Вы можете заменить элемент на reset их.
В этом случае вам нужно jQuery live()
, чтобы связать событие, потому что ваше поле ввода будет динамически (повторно) создано.
Это будет работать во всех браузерах.
Я нашел это решение в ответе stackoverflow Очистка input type='file' с помощью jQuery
$(".attachmentsUpload input.file").live("change", function () {
if ($(".attachmentsUpload input.file").val() == "") {
return;
}
// get the inputs value
var fileInputContent = $(".attachmentsUpload input.file").val();
// your ajax submit
alert("submit value of the file input field=" + fileInputContent);
// reset the field
$(".attachmentsUpload input.file").replaceWith('<input type="file" class="file" name="file" />');
});
Дополнительная информация
Ознакомьтесь с моим обновленным jsFiddle
Ответ 2
На основе ответа dknaack ключом является использование jquery live для привязки события изменения и сброса поля ввода после отправки:
$(document).ready(function () {
$(".attachmentsUpload input.file").change(function () {
$('form').submit(); /* sync submit */
$(".attachmentsUpload input.file").replaceWith('<input type="file" class="file" name="file" />');
});
});
Сброс должен выполняться после отправки. Когда submit async, reset поле, например, в событии ajax success.
$(document).ready(function () {
$(".attachmentsUpload input.file").change(function () {
$('form').submit(); /* async submit */
});
});
.ajaxForm({
...
success: function (result) {
// reset the field - needed for IE to upload the same file second time
$this.find("input.file").replaceWith('<input type="file" class="file" name="file" />');
}
});
Ответ 3
Убедитесь, что ваш script завернут в оболочку $(function() {})
.
Похоже, что он выполняется до того, как DOM готов.