First of all, I want to stress that <input type="file" />
will not upload the file automatically, unless you do something with ajax or the user submits the form. The user just tells the browser where it can find the file in case the user wants to submit the form at some point.
To find out what happened I made this script. The tab doesn't register if I put it on the input-field, so I put it on the parent of the input field instead. The rest works based on that it executes handlers in the order they were attached.
If the user takes more than 1/10th of a second to choose a file (or cancel the upload), which is almost always the case. I set data with the timestamp when a certain action happens that would gain the input field focus, that isn't by closing the upload dialog (e.g. by choosing a file or by hitting escape/clicking cancel). If the input field gets focus within 1/10th of a second when that happens, I know it isn't the event we are looking for. The second thing we check, is if the value changes. If the user cancels the dialog, the value doesn't change. That is when the user has canceled the dialog... somehow... and still want to upload the same file. If the value does change, the user changed their mind about what file to upload. The file doesn't update until the user submits the forum though.
HTML:
<input type="file" id="example" />
Javascript (with jquery):
$(document).ready( function() {
$('#example').parent().on( 'keydown', function(e) {
var key = e.key || e.keyCode || e.which;
if( key == "Tab" || key == 9) {
$('#example').data( 'actiontime', +new Date() );
}
} );
$('#example').on( 'blur', function() {
$(this).data( 'lastval', $(this).val() );
} ).on('mousedown', function() {
$(this).data( 'actiontime', +new Date() );
} ).on('focus', function() {
var fastevents = new Date() - $(this).data( 'actiontime' ) < 100;
if( $(this).data( 'lastval' ) == undefined ) {
console.log( 'First run' );
} else if( $(this).data( 'lastval' ) != $(this).val() && !fastevents ) {
console.log( 'Input changed' );
} else if( !fastevents ) {
console.log( 'User canceled dialog somehow' );
} else {
console.log( 'Other event' );
}
});
});