Второе использование входного файла больше не запускает onchange

У меня есть кнопка загрузки изображения, которая автоматически загружает файл при выборе из окна просмотра.
Тем не менее, он не работает во второй раз, и это связано с тем, что событие onChange не запускается. Почему это так?

Вот пример использования:
1. При щелчке кнопки я вызываю uploadMessagePicture(), который открывает окно просмотра.
2. Когда пользователь выбрал изображение, обнаружено событие onChange, которое запускает ajaxFileUpload() и отображает область редактора фотографий.
3. Когда загрузка завершена, отображается предварительный просмотр изображения. 4. Пользователь удаляет изображение, вызывая deleteMessageImage() (который также очищает поля и скрывает редактор фотографий).
5. Пользователь пытается загрузить другое изображение.

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

Вот HTML:

<a class="im-photo-btn" href="javascript:;" onclick="javascript:uploadMessagePicture();"><i class="icon-join-photo"></i></a>

<div class="editor-photoarea" id="editor-photoarea" style="display:none;">
    <input name="image_message_file" type="hidden" id="image_message_file" value="" />
    <div id="image_message_upload">
        <input name="image-message" type="file" id="image-message" style="display:none; visibility:hidden;" /> 
        <!-- hide it and trigger it from the photo btn (need both display:none + visibility:hiden for browser compatibility) -->
    </div>
    <div class="loading" id="image_message_loading" style="display:none;"><img alt="<?php echo $lang["Loading"];?>" src="lib/immedia/img/ajax-loader.gif" /> <?php echo $lang["Loading"];?></div>
    <div class="preview" style="display:none;" id="image_message_preview">
        <!-- <div>Image preview :</div>
        <div id='small_message_msg'></div>
            <img src='' />
            <div class='btnoptions'>
                <a onclick='javascript:deleteMessageImage();' href='javascript:;' class='button' title="Delete photo">
                    <span class='ui-icon ui-icon-closethick smsg'></span>Delete
                </a>
         </div>-->
</div>

Вот javascript для автоматической загрузки изображения

$(document).ready(function (){
    $("#image-message").on('change', function () {
        $('#editor-photoarea').show();
        ajaxFileUploadMessagePicture();
    });
});

function uploadMessagePicture(){
    //trigger the browse click
    if($('#image_message_file').val() == ''){
        //let the person upload a file only if none are there
        $('#image-message').trigger('click');
    }
}

function ajaxFileUploadMessagePicture(){
$("#msg_error_no_image_message").hide();

var imageName = $("#image-message").val();
if(imageName != ''){
    $("#image_message_loading").show();
    $('#sendBtn').attr('disabled', 'disabled');

    $.ajaxFileUpload
    (
        {
            url:siteRegionDir+'lib/immedia/uploadMessagePicture.php',
            secureuri:false,
            fileElementId:'image-message',
            dataType: 'json',
            success: function (data, status)
            {
                updateMessagePicture(data);             
            },
            error: function (data, status, e)
            {
                alert(e);
            }
        }
    )   
}else{
    $("#msg_error_no_image_message").show();
}
return false;
}

Вот Javascript, чтобы удалить изображение и очистить поля

function deleteMessageImage(){
//delete the image
var file = $("#image_message_file").val();

if(file != '') {
    $.post(siteRegionDir+'lib/immedia/deleteMessagePicture.php',{filename:file}, function(data) {   
            clearPictureAttachment();               
            $('#editor-photoarea').hide();//make sure it is hidden
        },"html"  
    );
}else{      
    clearPictureAttachment();
    $('#editor-photoarea').hide();//make sure it is hidden
}
}

function clearPictureAttachment(){
//var control = $("#image-message");
$("#image-message").attr('value', '');
//control.replaceWith( control = control.clone( true ) );//so it resets it all, truw = keep the bound events
$("#image_message_file").attr('value', '');
$("#image_message_loading").hide();
$("#image_message_upload").show();
$("#image_message_preview").hide();
}

Любая помощь будет замечательной! Спасибо!

Ответ 1

Благодаря кодовому ритму за то, что он меня на правильном пути.
То, что я сделал, - это просто добавить снова (on change) в поле.
Поэтому я только изменил функцию clearPictureAttachment() (вызываемую при удалении изображения):

function clearPictureAttachment(){
$("#image-message").attr('value', '');    
$("#image_message_file").attr('value', '');
$("#image_message_loading").hide();
$("#image_message_upload").show();
$("#image_message_preview").hide();
//reenable the onchange to upload a picture
$("#image-message").on('change', function () {
    $('#editor-photoarea').show();
    ajaxFileUploadMessagePicture();
});
}

Еще раз спасибо!

Ответ 2

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

Если вы выберете тот же файл, событие onChange input[type=file] не будет срабатывать.

Другой файл с тем же именем также не запускает событие. Выберите другой файл изображения - это произойдет.

Чтобы избежать этого, вы можете reset форму, чтобы убедиться, что выбор файла будет выполняться на чистом элементе управления file

Ответ 3

Синхронизировать - это частично право на событие onchange, которое не будет срабатывать для одного и того же файла. Более точно, в случае файла входного типа (сценарий, упомянутый ether), расположение файла для запуска события.

Попробуйте это после выбора любого файла

В jQuery $("#image_message_upload [type='file']")[0].value

Вы получите что-то вроде    " C:\fakepath\country-and-mobile-redirect-for-wordpress-dwpsxm-clipar.jpg" в качестве вывода (то есть расположение выбранного файла)

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

$("#image_message_upload [type='file']")[0].value=""

Итак, добавив эту строку (внутри clearPictureAttachment(), согласно этому вопросу) будет reset тип ввода файла, и вы можете выбрать один и тот же файл изображения без проблем.

Приветствия:)

Ответ 4

@Sync дал мне идею решить эту проблему.

Вот рабочий код, вам нужно клонировать входной файл.

var control = $('input[type=file]');
control.replaceWith( control = control.clone( true ) );

и событие все равно будет запущено во второй раз.

Ответ 5

В angular

HTML

<input #photoInput type="file" /> 

TS

export class SomeComponent {

 @ViewChild('photoInput') photoInput;

 clearPictureAttachment() {
  this.photoInput.nativeElement.value = '';
 }
}

Ответ 6

Если вы используете React или просто javascript в целом, вы можете также "сбросить" значение цели события.

Так что если у вас есть что-то вроде компонента, который может загрузить и "удалить" изображение:

<input type="file" onChange={onChange} />

Ваш onChange может быть:

onChange(event) {

    const files = target.files;

    // your logic here on what to do with files (maybe fetch the preview or something)

    // this line right below will reset the 
    // input field so if you removed it you can re-add the same file
    target.value = ''
}