【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

相关推荐
fouryears_234171 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~2 小时前
C#---StopWatch类
开发语言·c#
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
lifallen3 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
cui__OaO4 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端