直接说需求:需要实现在文件上传面板中限制需要的文件格式,并且不想展示“所有文件”这个选项,应该怎么做嘞?效果如下图:
这里用到了 window.showOpenFilePicker 方法实现,首先定义接受的格式及限制:
const pickerOpts = {types: [{description: 'Files',accept: {'application/pdf': ['.pdf'],'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx', '.doc'],'application/vnd.ms-excel': ['.xls'],'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx','.ppt']}}],excludeAcceptAllOption: true,multiple: state.allowMultipleUpload
};
这里如果按照下面这种写法来写,会导致出现.ppa和.dot格式的文件格式:
const pickerOpts = {types: [{description: 'Files',accept: {'application/pdf': ['.pdf'],'application/vnd.ms-word': ['.doc'],'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],'application/vnd.ms-excel': ['.xls'],'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],'application/vnd.ms-powerpoint': ['.ppt'],'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx']}}],excludeAcceptAllOption: true,multiple: state.allowMultipleUpload
};
下面是实现效果的关键代码:
try {if (window.showOpenFilePicker) {const fileHandles = await window.showOpenFilePicker(pickerOpts);const fileDatas = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));handleFileInput(fileDatas); // 这里进行后续的上传逻辑} else {const input = document.createElement('input');input.type = 'file';input.multiple = true;input.accept = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx';input.onchange = () => {if (input.files) {handleFileInput(Array.from(input.files)); // 这里进行后续的上传逻辑}};input.click();}
} catch (err) {console.log(err);
}
这里为什么是加了if..else,因为Safari浏览器和火狐浏览器不支持 window.showOpenFilePicker,因此需要向下兼容,使用原生的方法,不过这两个浏览器无法去掉“所有文件”这个选项,效果如下: