【JS】Web端访问文件夹,模拟网页版VS Code功能

前言

VS Code网页版支持访问并展示文件夹,https://vscode.dev/?vscode-lang=zh-cn,下面研究一下是如何实现的。

问题点

  • 如何打开并选择文件夹
  • 如何得到文件夹中的内容
  • 如何读到某个文件的内容
  • 如何高亮显示代码

实现

1. 打开并选择文件夹

通过showDirectoryPicker打开文件夹,该方法是异步的。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">选择文件夹</button>
  <script>
    btn.onclick = async function () {
      try {
        const handle = await showDirectoryPicker()
        console.log(handle);
      } catch (e) {
        // 用户拒绝浏览器访问文件
      }
    }
  </script>
</body>

</html>

允许浏览器查看文件

showDirectoryPicker会返回一个文件夹的处理句柄

2. 打开并选择文件夹

调用文件夹处理句柄entries方法可以拿到异步迭代器,对此进行循环即可拿到下一个文件的处理句柄

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">选择文件夹</button>
  <script>
    btn.onclick = async function () {
      try {
        const handle = await showDirectoryPicker()
        processHandle(handle)
      } catch (e) {
        // 用户拒绝浏览器访问文件
      }
    }

    async function processHandle(handle) {
      // 得到异步迭代器
      const iter = handle.entries()
      for await (const item of iter) {
        console.log(item);
      }
    }
  </script>
</body>

</html>

递归处理,得到根句柄

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">选择文件夹</button>
  <script>
    btn.onclick = async function () {
      try {
        const handle = await showDirectoryPicker()
        const root = await processHandle(handle)
        console.log(root);
      } catch (e) {
        // 用户拒绝浏览器访问文件
      }
    }

    async function processHandle(handle) {
      if (handle.kind === 'file') {
        return handle
      }
      handle.children = []
      // 得到异步迭代器
      const iter = handle.entries()
      for await (const item of iter) {
        handle.children.push(await processHandle(item[1])) // 递归确保是文件
      }

      return handle
    }
  </script>
</body>

</html>

3. 读取文件内容

通过getFile得到文件内容

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">选择文件夹</button>
  <script>
    btn.onclick = async function () {
      try {
        const handle = await showDirectoryPicker()
        const root = await processHandle(handle)
        const file = await root.children[0].getFile()
        const reader = new FileReader()
        reader.onload = function (e) {
          console.log(e.target.result);
        }
        reader.readAsText(file, 'utf-8')
      } catch (e) {
        // 用户拒绝浏览器访问文件
        console.log(e);
      }
    }

    async function processHandle(handle) {
      if (handle.kind === 'file') {
        return handle
      }
      handle.children = []
      // 得到异步迭代器
      const iter = handle.entries()
      for await (const item of iter) {
        handle.children.push(await processHandle(item[1])) // 递归确保是文件
      }

      return handle
    }
  </script>
</body>

</html>

4. 高亮显示代码

三方库:highlight.js

相关推荐
喵了meme6 小时前
C语言实战4
c语言·开发语言
码界奇点6 小时前
Python从0到100一站式学习路线图与实战指南
开发语言·python·学习·青少年编程·贴图
9ilk6 小时前
【C++】--- 特殊类设计
开发语言·c++·后端
sali-tec7 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
老前端的功夫7 小时前
Vue 3 性能深度解析:从架构革新到运行时的全面优化
javascript·vue.js·架构
天天扭码7 小时前
如何实现流式输出?一篇文章手把手教你!
前端·aigc·ai编程
前端 贾公子7 小时前
vue移动端适配方案 === postcss-px-to-viewport
前端·javascript·html
生骨大头菜8 小时前
使用python实现相似图片搜索功能,并接入springcloud
开发语言·python·spring cloud·微服务
绝不收费—免费看不了了联系我8 小时前
Fastapi的单进程响应问题 和 解决方法
开发语言·后端·python·fastapi
GISer_Jing8 小时前
AI营销增长:4大核心能力+前端落地指南
前端·javascript·人工智能