You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 08:53:06