问题
I want to fire an event when the user select a file. Doing so with .change event it works if the user changes the file every time.
But I want to fire the event if the user select the same file again.
- User select file
A.jpg(event fires) - User select file
B.jpg(event fires) - User select file
B.jpg(event doesn't fire, I want it to fire)
How can I do it?
回答1:
You can trick it. Remove the file element and add it in the same place on change event. It will erase the file path making it changeable every time.
Example on jsFiddle.
Or you can simply use .prop("value", ""), see this example on jsFiddle.
- jQuery 1.6+
prop - Earlier versions
attr
回答2:
If you have tried .attr("value", "") and didn't work, don't panic (like I did)
just do .val("") instead, and will work fine
回答3:
You can simply set to null the file path every time user clicks on the control. Now, even if the user selects the same file, the onchange event will be triggered.
<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />
回答4:
I got this to work by clearing the file input value onClick and then posting the file onChange. This allows the user to select the same file twice in a row and still have the change event fire to post to the server. My example uses the the jQuery form plugin.
$('input[type=file]').click(function(){
$(this).attr("value", "");
})
$('input[type=file]').change(function(){
$('#my-form').ajaxSubmit(options);
})
回答5:
Use onClick event to clear value of target input, each time user clicks on field. This ensures that the onChange event will be triggered for the same file as well. Worked for me :)
onInputClick = (event) => {
event.target.value = ''
}
<input type="file" onChange={onFileChanged} onClick={onInputClick} />
Using TypeScript
onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
const element = event.target as HTMLInputElement
element.value = ''
}
回答6:
This work for me
<input type="file" onchange="function();this.value=null;return false;">
回答7:
VueJs solution
<input
type="file"
style="display: none;"
ref="fileInput"
accept="*"
@change="onFilePicked"
@click="$refs.fileInput.value=null"
>
回答8:
Inspiring from @braitsch I have used the following in my 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);
}
}
Here the onClick(event) rescued me :-)
回答9:
By default, the value property of input element cleared after selection of files if the input have multiple attributes. If you do not clean this property then "change" event will not be fired if you select the same file. You can manage this behavior using multiple attribute.
<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>
Reference
回答10:
You can't make change fire here (correct behavior, since nothing changed). However, you could bind click as well...though this may fire too often...there's not much middle ground between the two though.
$("#fileID").bind("click change", function() {
//do stuff
});
回答11:
If you don't want to use jQuery
<form enctype='multipart/form-data'>
<input onchange="alert(this.value); return false;" type='file'>
<br>
<input type='submit' value='Upload'>
</form>
It works fine in Firefox, but for Chrome you need to add this.value=null; after alert.
回答12:
Probably the easiest thing you can do is set the value to an empty string. This forces it to 'change' the file each time even if the same file is selected again.
<input type="file" value="" />
回答13:
You can use form.reset() to clear the file input's files list.
This will reset all fields to default values, but in many cases you may be only using the input type='file' in a form to upload files anyway.
In this solution there is no need to clone the element and re-hook events again.
Thanks to philiplehmann
回答14:
I ran into same issue, i red through he solutions above but they did not get any good explanation what was really happening.
This solution i wrote https://jsfiddle.net/r2wjp6u8/ does no do many changes in the DOM tree, it just changes values of the input field. From performance aspect it should be bit better.
Link to fiddle: 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>
回答15:
So, there is no way to 100% be sure they are selecting the same file unless you store each file and compare them programmatically.
The way you interact with files (what JS does when the user 'uploads' a file) is HTML5 File API and 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
These tutorials show you how to capture and read the metadata (stored as js object) when a file is uploaded.
Create a function that fires 'onChange' that will read->store->compare metadata of the current file against the previous files. Then you can trigger your event when the desired file is selected.
回答16:
Believe me, it will definitely help you!
// 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;
};
Hope this will help many of you guys.
回答17:
Create for the input a click event and a change event. The click event empties the input and the change event contains the code you want to execute.
So the click event will empty when you click the input button(before the select file windows opens), therefor the change event will always trigger when you select a file.
$("#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>
回答18:
Here's the React-y way solution i've found that worked for me:
onClick={event => event.target.value = null}
来源:https://stackoverflow.com/questions/4109276/how-to-detect-input-type-file-change-for-the-same-file