web-dev-qa-db-ja.com

入力type = "file"フィールドを使用して、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を使用してこのファイルを送信しています。これはここでは重要な部分ではありません。重要な点は、ダイアログボックスで2回目に同じファイルを選択している間、最初のファイルを送信した直後に、.change()イベントがIEおよびChromeで発生しないことです。別のファイルを選択すると、イベントが発生して正常に動作しますが、Firefoxでは常に発生しています。

(Firefoxのように)期待どおりに動作するように、これを回避する方法は?

22
jwaliszko

説明

これは、同じファイルを再度選択しても、入力フィールド(選択したファイルパス)の値が変わらないために発生します。

onChange()イベントの値を空の文字列に設定し、値が空でない場合にのみフォームを送信できます。私のサンプルとこれをご覧ください jsFiddle Demonstration

サンプル

_$(".attachmentsUpload input.file").change(function () {
    if ($(".attachmentsUpload input.file").val() == "") {
        return;
    }
    // your ajax submit
    $(".attachmentsUpload input.file").val("");
});
_

更新

これは、何らかの理由で、IE9では機能しません。要素を置き換えてリセットできます。 この場合、入力フィールドが動的に(再)作成されるため、jQuery live()がイベントをバインドする必要があります。これは動作しますすべてのブラウザで。

私はこのソリューションをstackoverflowの答えで見つけました 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 をチェックしてください

注:live is nowremovedjQueryの以降のバージョンから。 onの代わりに live を使用してください。

29
dknaack

Dknaackの答えに基づくと、手がかりは変更イベントをバインドし、送信後に入力フィールドをリセットするjqueryライブの使用:です。

$(document).ready(function () {
    $(".attachmentsUpload input.file").change(function () {
        $('form').submit();  /* sync submit */
        $(".attachmentsUpload input.file").replaceWith('<input type="file" class="file" name="file" />');
    });
});

リセットを実行する必要があります送信後イベントが完了しました。送信がasyncの場合、たとえば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" />');
    }
});
1
jwaliszko