同じファイルの入力タイプ=ファイルの「変更」を検出するにはどうすればよいですか?


131

ユーザーがファイルを選択したときにイベントを発生させたい。.changeイベントでこれを行うと、ユーザーが毎回ファイルを変更した場合に機能します。

しかし、ユーザーが同じファイルを再度選択した場合にイベントを発生させたいと思います。

  1. ユーザー選択ファイルA.jpg(イベント発生)
  2. ユーザー選択ファイルB.jpg(イベント発生)
  3. ユーザーがファイルを選択しますB.jpg(イベントが発生しません。発生させたいです)

どうすればできますか?

回答:


78

あなたはそれをだますことができます。ファイル要素を削除し、changeイベントの同じ場所に追加します。ファイルパスを消去して、毎回変更できるようにします。

jsFiddleの例。

または.prop("value", "")、単に使用することもできます。jsFiddleのこの例を参照してください。

  • jQuery 1.6以降 prop
  • 以前のバージョン attr

@ペッカ:正確には違います。しかし、彼はそれを適応させることができます。彼がファイルを投稿する必要があるとしましょう。投稿後、新しいファイルセレクターを削除および追加するjs関数を呼び出すことができます。実行可能です。
BrunoLM

3
を使用するとき、.attr("value", "")または.val("")(@ wagner-leonardiが推奨するように)Internet Explorerが変更イベントを
起動するのは、Chromeが起動

4
「値」は財産ではなく、入力の属性があるため、お勧めjQueryの使い方は次のようになります.prop("value", "")
ロジャー・バレット

70

試して.attr("value", "")もうまくいかなくても、慌てないでください(私がしたように)。

.val("")代わりに行うだけで、正常に動作します


49

ユーザーがコントロールをクリックするたびに、ファイルパスをnullに設定するだけです。これで、ユーザーが同じファイルを選択した場合でも、onchangeイベントがトリガーされます。

<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />

2
このような解決策が必要でした。それは本当に短く、仕事を成し遂げます。いい考えマリウス・ウィアゾフスキー。
ジェイダルメンドラソランキ2018年

その他の解決策は、入力タグが変更されたときに値を変更することです。ただし、ファイルを選択した後で値が変更されることはありません。
songgeb 2018年

1
クール、ずっといい再び削除し、DOM内の要素を追加するよりも、THX
デヴィッド・ダルBUSCO

24

onClickイベントを使用して、ユーザーがフィールドをクリックするたびに、ターゲット入力の値をクリアします。これにより、同じファイルに対してonChangeイベントが確実にトリガーされます。私のために働いた:)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

TypeScriptの使用

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}

17

これを機能させるには、ファイルの入力値onClickをクリアしてから、ファイルonChangeをポストします。これにより、ユーザーは同じファイルを2回続けて選択し、変更イベントを発生させてサーバーに送信できます。私の例では、jQueryフォームプラグインを使用しています

$('input[type=file]').click(function(){
    $(this).attr("value", "");
})  
$('input[type=file]').change(function(){
    $('#my-form').ajaxSubmit(options);      
})

onClickonChangeに起動するので、この方法は私にとってはうまくいきます。
iplus26

8

この仕事は私にとって

<input type="file" onchange="function();this.value=null;return false;">

1
私はあなたがfunction(){this.value = null; falseを返します。}
Jacek Pietal 2014

7

VueJsソリューション

<input
                type="file"
                style="display: none;"
                ref="fileInput"
                accept="*"
                @change="onFilePicked"
                @click="$refs.fileInput.value=null"
>

1
このバリエーションの回答をありがとう
Coisox

5

@braitschからのインスピレーション私はAngularJS2で以下を使用しました input-file-component

<input id="file" onclick="onClick($event) onchange="onChange($event)" type="file" accept="*/*" />

export class InputFile {

    @Input()
    file:File|Blob;

    @Output()
    fileChange = new EventEmitter();

    onClick(event) {
        event.target.value=''
    }
    onChange(e){
        let files  = e.target.files;
        if(files.length){
            this.file = files[0];
        }
        else { this.file = null}
        this.fileChange.emit(this.file);
    }
}

ここでonClick(event)私を救った:-)


3

おそらく、最も簡単な方法は、値を空の文字列に設定することです。これにより、同じファイルが再度選択された場合でも、毎回ファイルが「変更」されます。

<input type="file" value="" />


3

これが私が見つけたReact-yの方法の解決策です:

onClick={event => event.target.value = null}


2

jQueryを使用したくない場合

<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

Firefoxでは問題なく動作しますが、Chromeの場合はthis.value=null;警告後に追加する必要があります。


2

デフォルトでは、入力に複数の属性がある場合、ファイルの選択後にinput要素のvalueプロパティがクリアされます。このプロパティをクリーンアップしないと、同じファイルを選択した場合、「変更」イベントは発生しません。この動作はmultiple属性を使用して管理できます。

<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>

参照


1

changeここで発砲することはできません(何も変わっていないため、正しい動作です)。ただし、結合できるclickだけでなく...これは火かもしれないが、あまりにも頻繁に... 2かの間に多くの妥協はありません。

$("#fileID").bind("click change", function() {
  //do stuff
});

あなたは単に彼の言葉を繰り返しているようで、.click()「再選択に火をつけている」わけではないようです。
BrunoLM 2010年

@BrunoLM-いいえ、そうではありません...しかし、あなたがこれを行うことができないと私が言う部分を読んだと思いますclick
Nick Craver

1

入力に対してクリックイベントと変更イベントを作成します。クリックイベントは入力を空にし、変更イベントには実行するコードが含まれます。

したがって、入力ボタンをクリックすると(選択ファイルウィンドウが開く前に)クリックイベントが空になるため、ファイルを選択すると、変更イベントが常にトリガーされます。

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

$("#input").change(function() {
  //Your code you want to execute!
});
<input id="input" type="file">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>


0

を使用form.reset()して、ファイル入力のfilesリストをクリアできます。これにより、すべてのフィールドがデフォルト値にリセットされますが、多くの場合、フォームで入力type = 'file'のみを使用してファイルをアップロードしている可能性があります。このソリューションでは、要素を複製してイベントを再度フックする必要はありません。

おかげphiliplehmann


0

私は同じ問題に遭遇しました、私は上記の彼の解決策を通して赤くなりましたが、彼らは本当に何が起こっているのかについての良い説明を得ませんでした。

このソリューションは私がhttps://jsfiddle.net/r2wjp6u8/を書いたは、DOMツリーで多くの変更を行わず、入力フィールドの値を変更するだけです。パフォーマンスの面からは、少し良くなるはずです。

フィドルへのリンク:https : //jsfiddle.net/r2wjp6u8/

<button id="btnSelectFile">Upload</button>

<!-- Not displaying the Inputfield because the design changes on each browser -->
<input type="file" id="fileInput" style="display: none;">
<p>
  Current File: <span id="currentFile"></span>
</p>
<hr>
<div class="log"></div>


<script>
// Get Logging Element
var log = document.querySelector('.log');

// Load the file input element.
var inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', currentFile);

// Add Click behavior to button
document.getElementById('btnSelectFile').addEventListener('click', selectFile);

function selectFile() {
  if (inputElement.files[0]) {
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    // Reset the Input Field
    log.innerHTML += '<p>Removing file: ' + inputElement.files[0].name + '</p>'
    inputElement.value = '';
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    log.innerHTML += '<hr>'
  }

  // Once we have a clean slide, open fiel select dialog.
  inputElement.click();
};

function currentFile() {
    // If Input Element has a file
  if (inputElement.files[0]) {
    document.getElementById('currentFile').innerHTML = inputElement.files[0].name;
  }
}

</scrip>

0

したがって、各ファイルを保存してプログラムで比較しない限り、同じファイルを確実に選択する方法はありません。

ファイルを操作する方法(ユーザーがファイルを「アップロード」したときにJSが行うこと)は、HTML5ファイルAPIJS FileReaderです。

https://www.html5rocks.com/en/tutorials/file/dndfiles/

https://scotch.io/tutorials/use-the-html5-file-api-to-work-with-files-locally-in-the-browser

これらのチュートリアルは、ファイルがアップロードされたときにメタデータ(jsオブジェクトとして保存されている)をキャプチャして読み取る方法を示しています。

現在のファイルのメタデータを以前のファイルと読み取り->保存->比較する「onChange」を起動する関数を作成します。次に、目的のファイルが選択されたときにイベントをトリガーできます。


0

私を信じて、それは間違いなくあなたを助けるでしょう!

// there I have called two `onchange event functions` due to some different scenario processing.

<input type="file" class="selectImagesHandlerDialog" 
    name="selectImagesHandlerDialog" 
    onclick="this.value=null;" accept="image/x-png,image/gif,image/jpeg" multiple 
    onchange="delegateMultipleFilesSelectionAndOpen(event); disposeMultipleFilesSelections(this);" />


// delegating multiple files select and open
var delegateMultipleFilesSelectionAndOpen = function (evt) {

  if (!evt.target.files) return;

  var selectedPhotos = evt.target.files;
  // some continuous source

};


// explicitly removing file input value memory cache
var disposeMultipleFilesSelections = function () {
  this.val = null;
};

これが皆さんの多くに役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.