【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

相关推荐
liuyouzhang3 小时前
将基于Archery的web数据库审计查询平台封装为jdbc接口的可行性研究(基于AI)
前端·数据库
不吃香菜学java8 小时前
Redis的java客户端
java·开发语言·spring boot·redis·缓存
码事漫谈8 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
贵沫末9 小时前
python——打包自己的库并安装
开发语言·windows·python
这儿有一堆花9 小时前
前端三件套真的落后了吗?揭开现代 Web 开发的底层逻辑
前端·javascript·css·html5
文祐9 小时前
C++类之虚函数表及其内存布局(一个子类继承一个父类)
开发语言·c++
.Cnn9 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
zuowei28899 小时前
华为网络设备配置文件备份与恢复(上传、下载、导出,导入)
开发语言·华为·php
醉酒的李白、10 小时前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
xiaohe0710 小时前
超详细 Python 爬虫指南
开发语言·爬虫·python