web-dev-qa-db-ja.com

入力ファイルを2回使用しても、onchangeはトリガーされなくなりました

閲覧ウィンドウから選択すると、ファイルを自動的にアップロードする画像アップロードボタンがあります。
それでも、2回目は機能しません。これは、onChangeイベントがトリガーされないためです。どうしてこんなことに?

ここにユースケースがあります:
1。ボタンをクリックすると、uploadMessagePicture()を呼び出して、参照ウィンドウを開きます。
2。ユーザーが画像を選択すると、ajaxFileUpload()をトリガーして写真エディター領域を表示するonChangeイベントが検出されます。
3。アップロードが完了すると、画像のプレビューが表示されます。 4.ユーザーは、deleteMessageImage()を呼び出して画像を削除します(これにより、フィールドがクリアされ、フォトエディターが非表示になります)。
5。ユーザーが別の画像をアップロードしようとしました。

この時点で参照ウィンドウが表示されますが、画像を選択してもonChangeイベントがトリガーされないため、何も起こりません...(また、ファイル名が入力値フィールドに転送されていないようです)。
Firefox23.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();
}

どんな助けでも素晴らしいでしょう!ありがとう!

17
ether

私を正しい方向に導いてくれたcodingrhythmに感謝します。
私がしたことは、実際にフィールドに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();
});
}

再度、感謝します!

5
ether

私の推測では、同じ画像ファイルを使用して機能を何度もテストしていると思います。

同じファイルを選択した場合、input[type=file]のonChangeイベントは発生しません。

同じ名前の別のファイルでもイベントは発生しません。別の画像ファイルを選択してください-それは起こります。

これを回避するには、フォームをリセットして、ファイルの選択がクリーンなfileコントロールで実行されるようにします。

11
Sych

Synchは、同じファイルに対して起動されないonchangeイベントについて部分的に正しいです。より正確には、入力タイプfileの場合のonchange(etherで言及されているシナリオ)は、ファイルの場所を考慮します。イベントのトリガー。

ファイルを選択した後、これを試してください

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

出力として「C:\ fakepath\country-and-mobile-redirect-for-wordpress-dwpsxm-clipar.jpg」のようなものが得られます(これは選択されたファイルの場所です)

これは、ファイル名またはその場所を変更することを意味しますが、これは正しくありません。したがって、より論理的には、ファイルの削除中にできることは、入力値属性をempty("")に設定することです。

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

したがって、この行を追加すると(この質問のように、clearPictureAttachment()内に)、ファイル入力タイプがリセットされ、同じ画像ファイルを問題なく選択できます。

乾杯:)

10
MKP

Reactまたは一般的にJavaScriptのみを使用している場合は、イベントターゲットの値を「リセット」することもできます。

したがって、画像をアップロードおよび「削除」できるコンポーネントのようなものがある場合は、次のようになります。

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

onChangeは次のようになります。

onChange(event) {

    const files = event.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
    event.target.value = ''
}
5
I am L

@Syncは、この問題を解決するためのアイデアを私に与えてくれました。

これが作業コードです。あなたがする必要があるのは、ファイル入力のクローンを作成することです。

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

イベントは引き続き2回目に発生します。

3
codingrhythm

角度で

HTML

<input #photoInput type="file" /> 

TS

export class SomeComponent {

 @ViewChild('photoInput') photoInput;

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

ファイルでやりたいことを行ったら、FileListをリセットできます。

私のReactアプリではこれがあります:

const handleLoad = evt => {
  if (evt.target.files && evt.target.files[0]) {
    dispatch(loadFile(evt.target.files[0].path));
  }
  // Reset the FileList, as otherwise the second and subsequent times
  // we browse, nothing will happen, because nothing changed.
  evt.target.files = new FileList();
};
0
Julian Mann