web-dev-qa-db-ja.com

同じファイルの入力type = file "change"を検出する方法は?

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

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

  1. ユーザー選択ファイルA.jpg(イベントが発生)
  2. ユーザー選択ファイルB.jpg(イベントが発生)
  3. ユーザー選択ファイルB.jpg(イベントが発生しない、発生させたい)

どうすればいいですか?

98
Gadonski

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

jsFiddleの例

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

  • jQuery 1.6+ prop
  • 以前のバージョンattr
66
BrunoLM

.attr("value", "")を試しても動作しなかった場合、パニックにならないでください(私がやったように)

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

68
Wagner Leonardi

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

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

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

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

ユーザーがフィールドをクリックするたびに、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 = ''
}
13
Trafalgar Law

私のためのこの仕事

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

VueJsソリューション

<input
                type="file"
                style="display: none;"
                ref="fileInput"
                accept="*"
                @change="onFilePicked"
                @click="$refs.fileInput.value=null"
>
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
MKJ

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

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

参照

2
Pulkit Aggarwal

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;アラート後。

1
elshnkhll

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

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

1
Curt

ここでchangeを起動させることはできません(何も変更されていないため、正しい動作です)。ただし、clickをバインドすることもできます...これはtooを頻繁に起動する可能性がありますが、2つの間にはあまり中間点がありません。

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

私は同じ問題にぶつかりました。私は上記の彼の解決策に目を通しましたが、実際に何が起こっているのかについての良い説明は得られませんでした。

このソリューションは、私が書いた 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
Ballpin

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

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

$("#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
hoi ja

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

philiplehmann に感謝

0
Rui Nunes

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

ファイルを操作する方法(ユーザーがファイルを「アップロード」するときにJSが行うこと)は、 HTML5 File API および JS 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;
};

これが皆さんの多くを助けることを願っています。

0
ArifMustafa