JavaScript - input file dialog closed event
In this short article, we would like to show how for input file element, handle dialog closed event.
By default it is not possible to handle dialog close event in JavaScript. The solution presented in the article uses trick based on getting window focus back after file dialog is closed.
The solution tracks window focus state and fires event when dialog is closed.
xxxxxxxxxx
<html>
<body>
<input id="file" type="file" />
<script>
function addDialogClosedListener(input, callback) {
var onFocus = function() {
window.removeEventListener('focus', onFocus);
callback();
};
var onClick = function() {
window.addEventListener('focus', onFocus);
};
input.addEventListener('click', onClick);
return function() {
input.removeEventListener('click', onClick);
window.removeEventListener('focus', onFocus);
};
}
// Usage example:
var file = document.querySelector('#file');
addDialogClosedListener(file, function() {
console.log('File dialog closed!');
});
</script>
</body>
</html>
This section contains improved above solution.
It tracks window focus state and fires delayed event when dialog is closed. That solution helps to solve problems related with multiple dialogs (one after the other), e.g. directory upload dialog with displayed additional warning dialog.
The example shows how to handle dialog closed event on directory selection input. Select some big directory to see the effect.
xxxxxxxxxx
<html>
<body>
<input id="file" webkitdirectory type="file" />
<script>
function addDialogClosedListener(input, callback) {
var id = null;
var active = false;
var wrapper = function() {
if (active) {
active = false;
callback();
}
};
var cleanup = function() {
clearTimeout(id);
};
var shedule = function(delay) {
id = setTimeout(wrapper, delay);
};
var onFocus = function() {
cleanup();
shedule(1000); // change the value to bigger if needed
};
var onBlur = function() {
cleanup();
};
var onClick = function() {
cleanup();
active = true;
};
var onChange = function() {
cleanup();
shedule(0);
};
input.addEventListener('click', onClick);
input.addEventListener('change', onChange);
window.addEventListener('focus', onFocus);
window.addEventListener('blur', onBlur);
return function() {
input.removeEventListener('click', onClick);
input.removeEventListener('change', onChange);
window.removeEventListener('focus', onFocus);
window.removeEventListener('blur', onBlur);
};
}
// Usage example:
var file = document.querySelector('#file');
addDialogClosedListener(file, function() {
console.log('Directory dialog closed!');
});
</script>
</body>
</html>