如何在JavaScript中一次性同时选择多个文件与文件夹的混合内容?
如何在JavaScript中一次性同时选择多个文件与文件夹的混合内容?
嗨,我明白你现在的困扰——原生的文件选择器默认没法同时混合多选文件和文件夹,确实有点麻烦。咱们来一步步解决这个问题:
首先先梳理下你当前遇到的局限:
- 用
<input type="file" multiple>时,只能选多个文件,没法选文件夹; - 加上
webkitdirectory/mozdirectory属性后,虽然能选文件夹,但默认只能选单个,而且没法同时选文件,这是因为这类属性会把选择器限制为仅文件夹模式。
接下来给你两个可行的方案,你可以根据需求选择:
方案1:利用File System Access API(推荐,现代浏览器支持)
这个API是Chrome 86+、Edge 86+等现代浏览器提供的,能直接让用户同时选择文件和文件夹,还支持多选,而且能灵活处理文件夹结构。代码示例如下:
async function selectMixedItems() { try { // 调用文件选择器,允许混合选择文件和文件夹 const handleList = await window.showOpenFilePicker({ multiple: true, types: [], // 不限制文件类型,按需调整 excludeAcceptAllOption: false, startIn: 'desktop' // 可选,设置默认打开的起始位置 }); // 遍历所有选中的项,区分文件和文件夹 for (const handle of handleList) { if (handle.kind === 'file') { const file = await handle.getFile(); console.log('选中的文件:', file.name); // 这里可以添加处理文件的逻辑 } else if (handle.kind === 'directory') { console.log('选中的文件夹:', handle.name); // 如果需要遍历文件夹内的所有文件,可以用递归方法 async function traverseDirectory(dirHandle) { for await (const entry of dirHandle.values()) { if (entry.kind === 'file') { const file = await entry.getFile(); console.log('文件夹内的文件:', file.name); } else if (entry.kind === 'directory') { await traverseDirectory(entry); } } } await traverseDirectory(handle); } } } catch (err) { console.error('选择操作失败:', err); } } // 绑定一个按钮来触发选择操作 document.getElementById('selectBtn').addEventListener('click', selectMixedItems);
这个方法的优势是体验更好,能直接区分文件和文件夹,还能递归处理文件夹内容,适合需要深度操作文件结构的场景。
方案2:利用input标签的扩展属性(仅Chromium系浏览器支持)
在Chrome、Edge这类基于Chromium的浏览器中,你可以给带webkitdirectory的input加上includeFiles属性,这样就能允许用户同时选择文件和文件夹,同时保留multiple实现多选:
<input type="file" id="filePicker" multiple webkitdirectory includeFiles>
然后在JavaScript中处理选中的结果:
document.getElementById('filePicker').addEventListener('change', (e) => { const selectedItems = e.target.files; for (const item of selectedItems) { // 注意:这里会把文件夹下的所有文件都平铺返回 // 可以通过webkitRelativePath判断是否属于某个文件夹 console.log('选中项:', item.name, '相对路径:', item.webkitRelativePath); } });
不过这个方法有局限性:includeFiles是非标准属性,只有Chromium系浏览器支持,而且无法直接获取文件夹本身的信息,只能通过文件的相对路径来推断层级。
总结一下:如果你的用户群体主要使用现代Chromium浏览器,方案2简单易实现;如果需要更好的兼容性和更灵活的文件结构处理,方案1的File System Access API是更优的选择。
备注:内容来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

