文件选择窗口
正常我们使用input type="file"属性上传文件,会唤起系统的文件选择器如下:
打开按钮
可以通过change事件监听:
// 增加的部分:创建 loading 实例变量
let loadingInstance;
let box = document.createElement('div');
document.body.appendChild(box);
box.setAttribute('style', 'display: block; height: 0; width: 0; overflow: hidden;');
let input = document.createElement('input');
input.setAttribute('name', 'file');
input.setAttribute('type', 'file');
input.setAttribute('multiple', 'multiple');
box.appendChild(input);
// 文件选择框弹出前,显示 loading
loadingInstance = Loading.service({ fullscreen: true, text: '正在上传...' });
const closeLoadingAndCleanup = () => {
document.body.removeChild(box);
if (loadingInstance) loadingInstance.close();
};
input.click();
input.addEventListener('change', function() {
let files = input.files;
if (files.length > 0) {
cb(files);
} else {
// 如果用户没有选中任何文件,也可以认为是一种取消操作,关闭加载框
closeLoadingAndCleanup();
}
});
但是如果,这个时候点击取消按钮,或者x关闭弹窗,原生的input标签是无法监听取消事件的。并且取消也不会触发input的change事件,这种情况下该怎么处理?
前提知识:
浏览器页面获取焦点事件早于 onchange 事件约20毫秒。
基于此点,我们可以监听focus事件,设置一个setTimeout ,那只要控制这个focus事件在change事件之后执行,就可以通过设置一个变量和setTimeout方法实现
// 取消事件
window.addEventListener(
'focus',
() => {
setTimeout(() => {
if (!input.files.length) {
// 取消逻辑处理
closeLoadingAndCleanup();
}
}, 300)
},
{ once: true }
)