web-dev-qa-db-ja.com

JQueryを使って<input type = 'file' />をクリアする

JQueryで<input type='file' />コントロール値をクリアすることは可能ですか?私は以下を試しました:

$('#control').attr({ value: '' }); 

しかし、うまくいきません。

526
sagar

簡単です:<form>を要素の周りにラップし、フォーム上でresetを呼び出し、そして.unwrap()を使ってフォームを削除します。このスレッドの他の.clone()ソリューションとは異なり、最後には同じ要素が設定されています(それに設定されたカスタムプロパティを含みます)。

テスト済みで、Opera、Firefox、Safari、Chrome、およびIE6 +で動作しています。 type="hidden"を除いて、他のタイプのフォーム要素でも動作します。

window.reset = function(e) {
  e.wrap('<form>').closest('form').get(0).reset();
  e.unwrap();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form>
  <input id="file" type="file">
  <br>
  <input id="text" type="text" value="Original">
</form>

<button onclick="reset($('#file'))">Reset file</button>
<button onclick="reset($('#text'))">Reset text</button>

JSFiddle

下記のTimoが指摘するように、<form>の中のフィールドのリセットを引き起こすボタンがある場合、<button>が送信を引き起こさないようにするためにイベントで.preventDefault()を呼ばなければなりません。


編集

未修正のバグのため、IE 11では機能しません。テキスト(ファイル名)は入力時に消去されますが、そのFileリストは入力されたままです。

517
slipheed

クイックアンサー:それを交換してください。

以下のコードでは、コントロールをそれ自身のクローンに置き換えるために replaceWith jQueryメソッドを使用します。このコントロールのイベントにハンドラがバインドされている場合は、それらも保持します。これを行うには、 true メソッドの最初のパラメータとしてcloneを渡します。

<input type="file" id="control"/>
<button id="clear">Clear</button>
var control = $("#control");

$("#clear").on("click", function () {
    control.replaceWith( control = control.clone( true ) );
});

フィドル: http://jsfiddle.net/jonathansampson/dAQVM/ /

イベントハンドラを維持しながらクローン作成を行うと、親要素からこのコントロールへのクリックを処理するためにイベント委任を使用することを検討できるすべての問題が発生します。

$("form").on("focus", "#control", doStuff);

これにより、コントロールが更新されているときに、要素と共にハンドラを複製する必要がなくなります。

430
Sampson

Jqueryはあなたのためにクロスブラウザ/古いブラウザの問題の面倒を見ることになっています。

これは私がテストした最新のブラウザで動作します:Chromium v​​25、Firefox v20、Opera v12.14

Jquery 1.9.1を使う

HTML

<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>

お酒

$("#clear").click(function () {
    $("#fileopen").val("");
});

On jsfiddle

次のjavascriptの解決策は、上記のブラウザでも私のために働きました。

document.getElementById("clear").addEventListener("click", function () {
    document.getElementById("fileopen").value = "";
}, false);

On jsfiddle

私はIEでテストする方法がありませんが、理論的にはこれでうまくいくはずです。 MSが別の方法で行ったためにIEのJavascriptバージョンが機能しないほど十分に異なる場合、jqueryメソッドは私の意見ではあなたのためにそれを扱うべきで、そうでなければそれは指摘する価値があるでしょうIEが必要とするメソッドと一緒にjqueryチーム。 (私は「これはIEでは機能しない」と言っている人がいるが、IEでどう機能するかを示すVanillaのジャバスクリプト(おそらく "セキュリティ機能"?)を述べていない。 MSも(もし彼らがそれをそのように数えるなら)、それがどんなより新しいリリースでも修正されるように)

別の回答で述べたように、 jqueryフォーラムの投稿

 if ($.browser.msie) {
      $('#file').replaceWith($('#file').clone());
 } else {
      $('#file').val('');
 }

しかしjqueryはブラウザテストのサポートを削除しました、 jquery.browser。

このjavascriptの解決策も私のために働いた、それは jquery.replaceWith メソッドのVanillaの同等物です。

document.getElementById("clear").addEventListener("click", function () {
    var fileopen = document.getElementById("fileopen"),
        clone = fileopen.cloneNode(true);

    fileopen.parentNode.replaceChild(clone, fileopen);
}, false);

On jsfiddle

注意すべき重要なことは、 cloneNode メソッドは関連するイベントハンドラを保存しないということです。

この例を見てください。

document.getElementById("fileopen").addEventListener("change", function () {
    alert("change");
}, false);

document.getElementById("clear").addEventListener("click", function () {
    var fileopen = document.getElementById("fileopen"),
        clone = fileopen.cloneNode(true);

    fileopen.parentNode.replaceChild(clone, fileopen);
}, false);

On jsfiddle

しかし jquery.clone これを提供しています [* 1]

$("#fileopen").change(function () {
    alert("change");
});

$("#clear").click(function () {
    var fileopen = $("#fileopen"),
        clone = fileopen.clone(true);

    fileopen.replaceWith(clone);
});

On jsfiddle

[* 1] イベントがjqueryのメソッドによって追加された場合、jqueryはこれを行うことができます。コピーは jquery.data に保存されます。それ以外の場合は機能しません。異なるメソッドやライブラリ間で互換性がありません。

document.getElementById("fileopen").addEventListener("change", function () {
    alert("change");
}, false);

$("#clear").click(function () {
    var fileopen = $("#fileopen"),
        clone = fileopen.clone(true);

    fileopen.replaceWith(clone);
});

On jsfiddle

添付されたイベントハンドラを要素自体から直接取得することはできません。

これがVanilla javascriptの一般原則です。これは、他のすべてのライブラリのjqueryが(おおよそ)行う方法です。

(function () {
    var listeners = [];

    function getListeners(node) {
        var length = listeners.length,
            i = 0,
            result = [],
            listener;

        while (i < length) {
            listener = listeners[i];
            if (listener.node === node) {
                result.Push(listener);
            }

            i += 1;
        }

        return result;
    }

    function addEventListener(node, type, handler) {
        listeners.Push({
            "node": node,
                "type": type,
                "handler": handler
        });

        node.addEventListener(type, handler, false);
    }

    function cloneNode(node, deep, withEvents) {
        var clone = node.cloneNode(deep),
            attached,
            length,
            evt,
            i = 0;

        if (withEvents) {
            attached = getListeners(node);
            if (attached) {
                length = attached.length;
                while (i < length) {
                    evt = attached[i];
                    addEventListener(clone, evt.type, evt.handler);

                    i += 1;
                }
            }
        }

        return clone;
    }

    addEventListener(document.getElementById("fileopen"), "change", function () {
        alert("change");
    });

    addEventListener(document.getElementById("clear"), "click", function () {
        var fileopen = document.getElementById("fileopen"),
            clone = cloneNode(fileopen, true, true);

        fileopen.parentNode.replaceChild(clone, fileopen);
    });
}());

On jsfiddle

もちろんjqueryや他のライブラリはそのようなリストを維持するのに必要な他のすべてのサポート方法を持っています、これは単なるデモンストレーションです。

104
Xotic750

明らかなセキュリティ上の理由から、空の文字列であってもファイル入力の値を設定することはできません。

あなたがしなければならないのは、フィールドがある場所のフォームをリセットすることです。もしあなたが他のフィールドを含むフォームのファイル入力をリセットしたいだけなら、これを使用してください:

function reset_field (e) {
    e.wrap('<form>').parent('form').trigger('reset');
    e.unwrap();
}​

ここに例があります: http://jsfiddle.net/v2SZJ/1/

48
Laurent

これは私のために働きます。

$("#file").replaceWith($("#file").clone());

http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie

それが役に立てば幸い。

43
SyntaxError

IE 8では、セキュリティのために[ファイルのアップロード]フィールドを読み取り専用にしました。 IEチームのブログ投稿 :を参照してください。

歴史的には、HTML File Upload Control()は、かなりの数の情報漏えいの脆弱性の原因となっていました。これらの問題を解決するために、コントロールの動作に2つの変更が加えられました。

キーストロークの盗用に頼ってユーザーを不正に操作してローカルファイルパスをコントロールに入力させる攻撃をブロックするために、[ファイルパス]編集ボックスは読み取り専用になりました。ユーザーはファイル参照ダイアログを使用してアップロードするファイルを明示的に選択する必要があります。

また、インターネットゾーンの「ファイルのアップロード時にローカルディレクトリパスを含める」URLActionが「無効」に設定されています。この変更により、機密性の高いローカルファイルシステム情報がインターネットに漏洩するのを防ぎます。たとえば、フルパスC:\ users\ericlaw\documents\secret\image.pngを送信するのではなく、Internet Explorer 8はファイル名image.pngのみを送信するようになりました。

20
Jon Galloway

$("#control").val('')はあなたが必要とするすべてです! JQuery 1.11を使用してChromeでテスト済み

他のユーザーもFirefoxでテストしました。

13
Bodi

私はここですべてのオプションにこだわった。これがうまくいったハックです。

<form>
 <input type="file">
 <button type="reset" id="file_reset" style="display:none">
</form>

次のようなコードでjQueryを使用してリセットをトリガーできます。

$('#file_reset').trigger('click');

(jsfiddle: http://jsfiddle.net/eCbd6/

12
Saneem

私はこれで終わりました:

if($.browser.msie || $.browser.webkit){
  // doesn't work with opera and FF
  $(this).after($(this).clone(true)).remove();  
}else{
  this.setAttribute('type', 'text');
  this.setAttribute('type', 'file'); 
}

最も洗練された解決策ではないかもしれませんが、私が言うことができる限りそれは働きます。

8
skvalen

私は https://github.com/malsup/form/blob/master/jquery.form.js を使用しました。これはclearInputs()と呼ばれる機能を持っています。IE issueを表示し、必要に応じて非表示フィールドを消去します。ファイル入力をクリアするための少し長い解決策かもしれませんが、クロスブラウザのファイルアップロードを扱う場合は、この解決策をお勧めします。

使い方は簡単です。

 //すべてのファイルフィールドを消去する:
 $( "input:file")。clearInputs(); 
 
 //隠しフィールドも消去する:
 $( "input:file")。clearInputs(true); 
 
 //特定のフィールドを消去する:
 $( "#myfilefield1、#myfilefield2")。clearInputs( ); 
/** 
 *選択したフォーム要素をクリアします。
 */
 $。fn.clearFields = $ .fn.clearInputs = function(includeHidden){[ var re =/^(?:color | date | datetime | email | month | number | password | range | search | tel | text | time | url | week)$/i; // 'hidden'はこのリストにありません
 return this.each(function(){
 var t = this.type、tag = this.tagName.toLowerCase(); 
 if(re.test(t)|| tag == 'textarea'){
 this.value = ''; 
} 
 else if(t == 'チェックボックス'|| t ==' radio '){
 this.checked = false; 
} 
そうでなければ(tag ==' select '){
 this .selectedIndex = -1; 
 else。(t == "file"){
 if(/MSIE/.test(navigator.userAgent)){
 $(this).replaceWith($(this).clone(true)); 
} else {
 $(this).val( ''); 
} 
} 
 else if(includeHidden){
 // includeHiddenにはtrueの値を指定できます。または、特殊なテストを示す選択文字列
 //を指定することもできます。例:
 // $( '#myForm')。clearForm( '。special:hidden')[.___ //((includeHidden === true && /hidden/.test(t))|| [.____。(//。if //((includeHidden === true &&/hidden/.test(t))|| 
) typeof includeHidden == 'string' && $(this).is(includeHidden)))
 this.value = ''; 
} 
}); 
 }; 
8
Timo Kähkönen

ファイル入力の値は読み取り専用です(セキュリティー上の理由から)。プログラム的に空白にすることはできません(フォームのreset()メソッドを呼び出す以外に、そのフィールドよりも広い範囲を持つ)。

5
Quentin

私は以下のコードを使って私の仕事を動かすことができました:

var input = $("#control");    
input.replaceWith(input.val('').clone(true));
5
Purusartha

私はHTMLファイルの入力をクリアするためのシンプルでクリーンな方法を探していました、上記の答えは素晴らしいです、しかし私がそれをする簡単でエレガントな方法でウェブに遭遇するまで、どれも本当に私が探しているものに答えません:

var $input = $("#control");

$input.replaceWith($input.val('').clone(true));

すべてのクレジットは Chris Coyier に行きます。

// Referneces
var control = $("#control"),
    clearBn = $("#clear");

// Setup the clear functionality
clearBn.on("click", function(){
    control.replaceWith( control.val('').clone( true ) );
});

// Some bound handlers to preserve when cloning
control.on({
    change: function(){ console.log( "Changed" ) },
     focus: function(){ console.log(  "Focus"  ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="file" id="control">
<br><br>
<a href="#" id="clear">Clear</a>
5
chebaby

私はこれをうまく動作させることができました。

function resetFileElement(ele) 
{
    ele.val(''); 
    ele.wrap('<form>').parent('form').trigger('reset');   
    ele.unwrap();
    ele.prop('files')[0] = null;
    ele.replaceWith(ele.clone());    
}

これはIE10、FF、Chrome、Operaでテストされています。

2つの注意点があります...

  1. それでもFFでは正しく機能しません。ページを更新すると、ファイル要素に選択したファイルが再設定されます。それがどこからこの情報を得ているかは私を超えています。ファイル入力要素に関連した他の何が私がクリアしようとすることができますか?

  2. ファイルのinput要素にアタッチしたイベントには必ず委任を使用してください。そうすれば、クローンが作成されたときにもそれらが機能します。

私が理解していないのは、無効な受け入れられないファイル選択から入力フィールドをクリアできないようにすることを地球上の誰が考えたのかということです。

ユーザーのOSからファイルにアクセスできないように動的に値を設定しないでください。ただし、フォーム全体をリセットせずに無効な選択を解除してください。

とにかく 'accept'がフィルタ以外のことをしているわけではありませんし、IE10ではMS WordのMIMEタイプさえ理解していません、冗談です!

4
1DMF

.clone()の事はOpera(そしておそらく他の人)では しない で動作します。内容を保持します。

ここで私に最も近い方法はJonathanの以前のものでしたが、フィールドがその名前、クラスなどを確実に保持するようにしたので、私の場合は面倒なコードになりました。

このようなものはうまくいくかもしれません(Quentinにも感謝します):

function clearInput($source) {
    var $form = $('<form>')
    var $targ = $source.clone().appendTo($form)
    $form[0].reset()
    $source.replaceWith($targ)
}
4
SpoonNZ

それはすべてのブラウザで私のために働きます。

        var input = $(this);
        var next = this.nextSibling;
        var parent = input.parent();
        var form = $("<form></form>");
        form.append(input);
        form[0].reset();
        if (next) {
            $(next).before(input);
        } else {
            parent.append(input);
        }
2
srsajid

私のFirefox 40.0.3ではこれだけで動作します

 $('input[type=file]').val('');
 $('input[type=file]').replaceWith($('input[type=file]').clone(true));
2
Roger Russel

私はユーザーが言ったテクニックのほとんどを試してみましたが、どれもすべてのブラウザでうまくいきませんでした。すなわち、clone()はファイル入力に対してFFでは機能しません。私は手動でファイル入力をコピーしてから、オリジナルをコピーしたものに置き換えました。全てのブラウザで動作します。

<input type="file" id="fileID" class="aClass" name="aName"/>

var $fileInput=$("#fileID");
var $fileCopy=$("<input type='file' class='"+$fileInput.attr("class")+" id='fileID' name='"+$fileInput.attr("name")+"'/>");
$fileInput.replaceWith($fileCopy);
1
Juan
function clear() {
    var input = document.createElement("input");
    input.setAttribute('type', 'file');
    input.setAttribute('value', '');
    input.setAttribute('id', 'email_attach');

    $('#email_attach').replaceWith( input.cloneNode() );
}
0

非同期にして、ボタンの目的の操作が行われた後にリセットします。

    <!-- Html Markup --->
    <input id="btn" type="file" value="Button" onchange="function()" />

    <script>
    //Function
    function function(e) {

        //input your coding here           

        //Reset
        var controlInput = $("#btn");
        controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
    } 
    </script>
0
JEPAAB

それは私のために動作しません:

$('#Attachment').replaceWith($(this).clone());
or 
$('#Attachment').replaceWith($('#Attachment').clone());

だからasp mvcで私はファイル入力を置き換えるためにかみそりの機能を使う。最初にIdとNameを使って入力文字列の変数を作成し、それをページに表示したりリセットボタンをクリックしたときに置き換えたりするためにそれを使います:

@{
    var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}

@attachmentInput

<button type="button" onclick="$('#@(Html.IdFor(p => p.Attachment))').replaceWith('@(attachmentInput)');">--</button>
0
Omid-RH

$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile'   style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());
0
Niraj

ただ使う

 $("#fileUploaderID").val(''); 
0
Thisara Subath