webkitRelativePath是什么?

webkitRelativePath 是一个在 HTML5 的 File API 中使用的非标准属性,它由 WebKit 和 Blink 引擎(如 Chrome 和 Safari 浏览器)支持。这个属性提供了一个相对于用户选择文件夹的路径,当用户通过 <input type="file" webkitdirectory> 选择整个目录时,该属性对每个文件对象可用。

主要特点:

  • 相对路径webkitRelativePath 提供的是一个字符串,表示文件相对于被选择的目录的路径。例如,如果用户选择了包含两个子文件夹 imagesdocs 的主文件夹,并且 images 文件夹内有一个名为 photo.jpg 的文件,那么对于 photo.jpg 文件对象,webkitRelativePath 的值将是 images/photo.jpg

  • 目录选择:只有当 <input type="file"> 元素设置了 webkitdirectory 属性并且用户选择了整个目录时,webkitRelativePath 才会有值。否则,此属性将为空字符串或未定义。

  • 非标准:需要注意的是,webkitRelativePath 并不是一个标准的 HTML 或 JavaScript 特性,因此它的使用可能会限制浏览器的兼容性。尽管如此,由于 WebKit 和 Blink 引擎的广泛使用,许多现代浏览器都支持这个特性。

使用场景:

webkitRelativePath 对于需要处理大量文件或者希望保持文件原有结构的应用特别有用,比如文件上传服务、云存储应用等。开发者可以利用这个属性来维持文件上传后的目录结构,或者根据文件所在的子目录来组织和分类文件。

示例代码:

下面是一个简单的例子,展示了如何使用 webkitRelativePath 来获取文件的相对路径:

<input type="file" id="folderInput" webkitdirectory directory multiple />
<script>
document.getElementById('folderInput').addEventListener('change', function(event) {
    const files = event.target.files;
    for (let i = 0; i < files.length; i++) {
        console.log(`File: ${files[i].name}, Path: ${files[i].webkitRelativePath}`);
    }
});
</script>

这段代码创建了一个文件输入元素,允许用户选择一个目录。当用户选择目录后,它会遍历所有选中的文件,并打印出每个文件的名字以及它的 webkitRelativePath

上述场景如何兼容不同的浏览器呢?

为了确保使用 webkitRelativePath 的场景在不同浏览器间具有良好的兼容性,你可以采取以下几种策略:

1. 检查浏览器支持

首先,应该检查当前浏览器是否支持 webkitdirectorywebkitRelativePath。这可以通过尝试访问这些属性来完成。

function isWebkitDirectorySupported() {
    var input = document.createElement('input');
    input.type = 'file';
    return 'webkitdirectory' in input && 'webkitRelativePath' in File.prototype;
}

2. 提供替代方案

对于不支持 webkitdirectorywebkitRelativePath 的浏览器,提供一个替代的选择机制。例如,允许用户逐个选择文件,或者通过拖拽方式上传文件,并手动构建文件结构。

<input type="file" id="folderInput" webkitdirectory directory multiple />
<input type="file" id="fileInput" multiple style="display:none;" />
<button onclick="document.getElementById('fileInput').click()">选择文件</button>

3. 使用 polyfill 或库

查找是否有任何 polyfill 或第三方库可以帮助实现跨浏览器的目录选择和相对路径解析。虽然目前没有广泛接受的 polyfill 可以直接模拟 webkitRelativePath,但你可以寻找类似的解决方案或创建自定义逻辑来模仿此功能。

4. 后端处理

如果前端难以解决兼容性问题,可以考虑将文件上传到服务器后,在后端处理文件结构。这样可以避免前端复杂的兼容性问题,同时利用服务器端更强大的处理能力来重构或解析文件夹结构。

5. 用户指导

为用户提供清晰的指导,说明哪些浏览器支持该功能,以及如果不支持时应如何操作。这可以通过页面上的提示信息、帮助文档或FAQ来实现。

6. 动态调整UI

根据浏览器的支持情况动态调整用户界面(UI)。例如,当检测到不支持 webkitdirectorywebkitRelativePath 时,隐藏相关的UI元素或禁用相关功能,并显示适当的提示信息。

示例代码

这里是一个改进后的示例代码,它会根据浏览器支持情况切换不同的文件选择方法:

<script>
function initFileInput() {
    const hasWebkitSupport = isWebkitDirectorySupported();
    
    if (hasWebkitSupport) {
        // 显示支持webkitdirectory的文件选择器
        document.getElementById('folderInput').style.display = 'block';
        document.getElementById('fileInput').style.display = 'none';
        document.getElementById('folderInput').addEventListener('change', handleFolderSelect);
    } else {
        // 显示普通文件选择器
        document.getElementById('folderInput').style.display = 'none';
        document.getElementById('fileInput').style.display = 'block';
        document.getElementById('fileInput').addEventListener('change', handleFileSelect);
    }
}

function handleFolderSelect(event) {
    const files = event.target.files;
    for (let i = 0; i < files.length; i++) {
        console.log(`File: ${files[i].name}, Path: ${files[i].webkitRelativePath}`);
    }
}

function handleFileSelect(event) {
    const files = event.target.files;
    for (let i = 0; i < files.length; i++) {
        console.log(`File: ${files[i].name}`);
    }
}

// 页面加载时初始化
window.onload = initFileInput;

function isWebkitDirectorySupported() {
    var input = document.createElement('input');
    input.type = 'file';
    return 'webkitdirectory' in input && 'webkitRelativePath' in File.prototype;
}
</script>

<input type="file" id="folderInput" webkitdirectory directory multiple style="display:none;" />
<input type="file" id="fileInput" multiple style="display:none;" />
<button onclick="document.getElementById('fileInput').click()">选择文件</button>

这段代码会根据浏览器是否支持 webkitdirectory 来决定显示哪个文件选择器,并相应地处理文件选择事件。这样可以在保持用户体验的同时,尽量覆盖更多的浏览器。

上传文件和文件夹

1、上传文件

设置属性 type="file" 可以选择文件,设置属性 multiple 可以多选

<input ref="fileInputRef" type="file" @change="onUpload" multiple class="upload-input" />
const onUpload = async (evt: any) => {
  console.log(evt.target.files);

  // 上传多文件
  const data = new FormData()
  data.append("files",  evt.target.files[0])
  data.append("files",  evt.target.files[1])
};

2、上传文件夹

设置属性 webkitdirectory 可以选择文件夹

<input
  type="file"
  @change="selectFolder"
  webkitdirectory
  class="upload-input" />
const selectFolder = async (evt: any) => {
  const files = evt.target.files;
  if (files.length > 0) {
    const fileDic = files[0].webkitRelativePath; // 文件夹名
  } else {
    window.$message.info('选择了一个空文件夹');
  }
};
posted @ 2024-12-28 16:01  龙陌  阅读(329)  评论(0)    收藏  举报