Событие изменения ввода файлов срабатывает только один раз

Я сделал небольшой script, используя некоторые из файлов HTML5, которые позволяют вам выбирать один или несколько файлов и каждый раз, когда он будет записывать имя файла (ов). Все работает так, как должно, только событие, чтобы обнаружить изменение стоимости файлов, вводимых только один раз, так как я могу заставить его срабатывать при каждом изменении, а не только при первом изменении?

Кстати, вот что я сделал: http://tamir.netspot.co.il/html5/files/

Ответ 1

Похоже, что прослушиватель событий change удаляется, потому что вы используете innerHTML для обновления того же элемента (wrapper), что сам вход находится внутри. Таким образом, содержимое элемента wrapper, включая ввод файла, перерисовывается, и по пути прослушиватель событий удаляется (или, скорее, он связан с элементом, который больше не существует).

Вот простой jsfiddle, который делает точно так же, как ваш код, за исключением того, что он печатает выбранные имена файлов в другом элементе, чем элемент вход в. И он работает (в WebKit, в любом случае)

Здесь дополнительные доказательства (я в основном скопировал ваш код и только добавил строку, чтобы перерегистрировать прослушиватель событий после изменения wrapper.innerHTML)

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


Я честно не знаю, является ли это законной ошибкой браузера или нет. Для innerHTML имеет смысл "перезаписать" существующий элемент ввода, но браузер достаточно умен, чтобы не было reset входного значения, поэтому вы могли бы подумать, что слушатели тоже будут придерживаться... так что... ну, это запутывает

Ответ 2

Если вы хотите дважды загрузить, сбросьте значение входного файла

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

jsfiddle test

Ответ 3

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

с jquery...

$('#myfileinputfieldid')[0].onchange = function(e) {
 //do something with e.  Like write an image to a canvas or make a yummy cup of coffee
  e.target.value = '';
};

Ответ 4

Вместо использования onchange использовать oninput event

 $scope.ShowIcon = function (input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                $('#iAIcon')
                    .attr('src', e.target.result)
            };
            reader.readAsDataURL(input.files[0]);           
        }        
    }

Ответ 5

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

Процесс для меня был:

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

Ответ 6

addEventListener не работает для IE8 (не уверен в IE9 и далее). Нам нужно использовать attachEvent listiner. Если вам нужна кросс-браузерная поддержка, используйте этот

if (!inputfile.addEventListener) {
    inputfile.attachEvent("onclick", setCheckedValues); //IE8
}else {
    inputfile.addEventListener("click", setCheckedValues, false); //Other browser
}

Ответ 7

ok хорошо в соответствии с @Flambino, вход повторно отображается. По какой бы причине это ни было, для меня это не имеет значения. Функциональность $.on('change', callback) теряется.

Попробуйте использовать функцию .delegate, которую я абсолютно люблю! http://api.jquery.com/delegate/

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

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

$(document).delegate('.file_upload_btn', 'change', function(){});

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

Ответ 8

Я получил обратный вызов.change для каждого нового файла, переназначив функцию.change в конце своего обратного вызова:

$('#myfileinputfieldid').change(function (event) {
    scope.processFile(event.target.files[0]);
});

scope.processFile = function(fileStruct) {
    doStuff;

    // Reassign the onchange callback.
    $('#myfileinputfieldid').change(function (event) {
        scope.processFile(event.target.files[0]);
    });
};

Ответ 9

В моем случае я использую AJAX для загрузки файла. Я просто очищаю значение ввода с помощью обработчика события onclick.

  $('#myFile').click(function(e) {e.target.value = '';});
  $('#myFile').change(function(e) { 
           var file = e.target.value;
           var formdata = new FormData();
           formdata.append('file', file, 'somefile');
           $.ajax({
             type: 'POST',
             url: './uploadFile',
             data: formdata,
             processData: false,
             contentType: false,
             success: function(data){

             }
        });
  });