网页版代码编辑器实现

news2024/9/23 9:37:28

接着前几天写的博客https://blog.csdn.net/woyebuzhidao321/article/details/131495855,提到了涉及vscode网页版工作区创建的api,这两天一时兴起,搞了一个网页版的代码编辑器,如果在2020年10月之前,实现一个网页版代码编辑器可能是天方夜谭,由于网页端操作本地文件的困难,很难搞得出,直到File System Access API的出现,打破了原来的瓶颈。

2020年10月 Chrome 86 重要更新

Chrome 86 在2020年10月推出了稳定版,现已全面应用于Android、Chrome OS、Linux、macOS 和 Windows等平台,我们一起来看下这次的重要更新。

若要看全部更新,请移步(https://www.chromestatus.com/features#milestone=86)。

新增稳定功能
文件系统访问

还记得Chrome 83中的本地文件系统吗,当时的试验功能,现已稳定。通过调用 showOpenFilePicker 方法,你可以唤起文件选择窗口,进而通过返回的文件句柄对文件进行读写。代码如下:

const pickerOpts = {
  types: [
    {
      description: "Images",
      accept: {
        "image/*": [".png", ".gif", ".jpeg", ".jpg"],
      },
    },
  ],
  excludeAcceptAllOption: true,
  multiple: false,
};
// create a reference for our file handle
let fileHandle;

async function getFile() {
  // open file picker, destructure the one element returned array
  [fileHandle] = await window.showOpenFilePicker(pickerOpts);

  // run code with our fileHandle
}

官方文档地址:
https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker

vscode网页版也是在此之后出现的。https://insiders.vscode.dev/

于是我照着大框实现了一个demo
Demo效果图
在这里插入图片描述
基于文件的增、删、改、查。读写速度很nice

打开文件夹

首先打开一个代码目录

$('#openFolderBtn')[0].addEventListener('click', async () => {
	try {
	// // 得到异步迭代器
		dirHandle = await window.showDirectoryPicker();

		const createTree = async () => {
			const root = await createTreeModel(dirHandle);
			fileArr = root;
			treeInit();
		}
		createTree();
		
	} catch (err) {
		console.log(err)
	}
})

在这里插入图片描述
这是会弹出一个文件弹窗
window.showDirectoryPicker是异步的 返回一个文件句柄,选中文件之后会出现提示
在这里插入图片描述
创建树的数据结构
在这里插入图片描述

读取文件

// 读取文件
async function reader() {
	if (fileHandle) {
		let file = await fileHandle.getFile();
		fileName.innerText = file.name;

		let reader = new FileReader();
		reader.onload = function (event) {
			let contents = escapeHtml(event.target.result);
			$("#textbox")[0].innerHTML = `<pre><code id="code">${contents}</code></pre>`;
			// hljs.highlightAll();
			hljs.highlightBlock($("#code")[0])
		};
		reader.readAsText(file);
	}
}

fileHandle是对应的文件句柄,通过调用getFile方法拿到文件,然后通过FileReader构造函数去读取文件内容并作展示

打开文件

如何单独打开一个本地文件

$('#openfile')[0].addEventListener('click', async () => {
	try {
		const openFileHandle = await window.showOpenFilePicker({
			types: [{
				accept: {
					"text/plain": [".txt"]
				}
			}],
			multiple: false
		});

		fileHandle = openFileHandle[0];
		reader();
	} catch (err) {
		console.log(err);
	}
})

选取一个文件并打开
在这里插入图片描述

如何创建一个文件夹

$("#createFolder")[0].addEventListener('click', async (e) => {
	const folderName = prompt('请输入文件夹名称');
	if (folderName) {
		await dirHandle.getDirectoryHandle(folderName, { create: true });
		console.log('文件夹创建成功');
		fileArrFlat = [];
		fileArr = await createTreeModel(dirHandle);
		treeInit();
	}
})

dirHandle是window.showDirectoryPicker返回的文件句柄,通过调用getDirectoryHandle方法创建。

创建一个文件

// 创建文件
$("#createFile")[0].addEventListener('click', async (e) => {
	const fileName = prompt('请输入文件名称');
	if (fileName) {
		try {
			if (!(await dirHandle.queryPermission()) === 'granted') {
				alert('文件不允许读写!');
				return;
			}
			const targetFile = await dirHandle.getFileHandle(fileName, { create: true });

			fileArrFlat = [];
			fileArr = await createTreeModel(dirHandle);
			treeInit();
		} catch (err) {
			console.log(err)
		}
	}
})

另存为文件并写入内容

// 另存为文件
	$("#textbox")[0].addEventListener('keydown', async (e) => {
		if (e.ctrlKey && e.which == 83) {
			e.preventDefault;
			console.log('文件另存为', $("#textbox")[0].innerText)
			try {
				fileHandle = await window.showSaveFilePicker({
					types: [{
						accept: {
							"text/plain": [".txt"]
						}
					}],
					multiple: false
				});
				const w$ = await fileHandle.createWritable();
				await w$.write($("#textbox")[0].innerText);
				await w$.close();
			} catch (err) {
				console.log(err);
			}

			return false;
		}
	}, false)

fileHandle文件句柄 提供了createWritable方法,对文件进行写入内容。

代码高亮部分使用的是highLight.js,这样一个最初版的网页版代码编辑器就搞定了

其兼容性
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/735552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

活动笔记 | 「企业人效提升路径」之数字化实践

6月27日&#xff0c;由人力资源智享会联合盖雅工场等机构主办的2023中国人力资源数字化论坛在北京顺利举办。盖雅工场高级解决方案顾问谷天毅先生发表了主题为 《企业人效提升路径之数字化实践》 的分享。 以下是分享内容&#xff0c;enjoy~ △ 盖雅工场高级解决方案顾问谷天…

httpx 返回都是乱码问题,非编码问题。

因为python 的requests 不能使用抓http2 的报文。所以看了一些httpx的使用。但是发现httpx 不能自动解压&#xff0c;text打印出来的都是乱码。一开始以为是编码格式的bug &#xff0c;但是使用chardet 确认了确实是utf-8.然后怀疑是压缩的问题。先去官网搜了一些文档 文档说会…

opencv4.7.0编译opencv-contrib-4.7.0以及CUDA

0、引言 最近工作中需要用到使用CUDA加速后的opencv进行传统算法的开发&#xff0c;在编程之前&#xff0c;需要先解决环境编译和lib库问题&#xff0c;本文就是记录自己编译opencv-4.7.0的全过程。 1、CUDA下载和安装 可参考我之前的博客WIN10安装配置TensorRT详解中的前几…

达尔文——生物医疗科学领域大模型

赛灵力官网 1. 生物医疗领域的挑战 1.1 复杂性 生物系统和生物过程非常复杂&#xff0c;包含大量的相互作用和调控机制&#xff0c;理解和解析这些复杂性是一项巨大的挑战。 举例来说&#xff0c;单单一个人类&#xff0c;体内的生物信息就非常复杂&#xff1a; 人类体内体内…

Django_re_path_使用正则匹配url

与path定义的路由相比&#xff0c;re_path 定义的路由可以使用正则表达式匹配url。 需要注意的是&#xff1a; 如果未定义匹配结果的变量名&#xff0c;匹配的结果默认传入视图的第2个形参。如果定义了匹配结果的变量名&#xff0c;匹配的结果会传给视图的同名字段&#xff0…

从零开始学习自动驾驶决策规划

从零开始学习自动驾驶决策规划 从入门到掌握的一系列讲解&#xff0c;其中涵盖的内容如下&#xff1a; 前言课 第一节-ros工程的创建 第一节-运行环境和工程目录简介第二节-工程运行和小车模型搭建简介 第二节-车辆里程计第三节-整体架构思路 第三节-地图路线构建方法 第三节…

Packet Tracer – 配置静态 NAT

Packet Tracer – 配置静态 NAT 目标 第 1 部分&#xff1a;测试不使用 NAT 的访问 第 2 部分&#xff1a;配置静态 NAT 第 3 部分&#xff1a;测试使用 NAT 的访问 拓扑图 场景 在 IPv4 配置网络中&#xff0c;客户端和服务器使用专用编址。 然后&#xff0c;在含专用编址…

MATLAB---线性规划问题求最优解(含例题)

线性规划是运筹学的基础&#xff0c;在现实企业经营中&#xff0c;如何有效的利用有限的人力、财力、物力等资源。 MATLAB 为方便大家理解&#xff0c;这里我们直接用一个例题为大家讲解使用matlab求解线性规划问题。 根据上图给出的线性规划问题。我们使…

SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理

SpringBoot 如何使用 ExceptionHandler 注解进行局部异常处理 介绍 在开发 Web 应用程序时&#xff0c;异常处理是非常重要的一部分。SpringBoot 提供了多种方式来处理异常&#xff0c;其中之一是使用 ExceptionHandler 注解进行局部异常处理。使用 ExceptionHandler 注解&am…

哈工大计算网络课程数据链路层详解之:数据链路层服务

哈工大计算网络课程数据链路层详解之&#xff1a;数据链路层服务 在介绍完网络层的实现功能和协议之后&#xff0c;接下来我们继续介绍网络层的下一层&#xff1a;数据链路层。 本节首先对数据链路层的功能和所提供的服务进行概述。 如下图示例网络所示&#xff0c;标红色的部…

【二分查找】34. 在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置 解题思路 使用二分查找查找到目标元素的索引之后然后向左以及向右寻找目标元素&#xff0c;然后记录下区间位置 然后保存下来 class Solution {public int[] searchRange(int[] nums, int target) {// 使用二分查找 数组有序…

Java使用Stream API对于数据列表经常处理

Java使用Stream API对于数据列表经常处理 先提供一些简单到复杂的常见例子&#xff0c;您可以根据这些例子进行进一步的开发和学习&#xff1a; 数据过滤筛选操作 查询表中所有数据&#xff1a; List<User> users userDao.getAllUsers();根据条件查询单个结果&#…

别测了,背锅上线!

三百六十行&#xff0c;行行都背锅。 用例千万条&#xff0c;质量第一条。 流程不规范&#xff0c;亲人两行泪&#xff01; 每次上线后多多少少都有些问题&#xff0c;每次的项目总结会总会生产一口新锅&#xff0c;等着你我他来背&#xff0c;这不又要上线了&#xff0c;这次…

华为OD机试真题 Java 实现【快递投放问题】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出 一、题目描述 有N个快递站点用字符串标识&#xff0c;某些站点之间有道路连接。每个站点有一些包裹要运输&#xff0c;每个站点间的包裹不重复&#xff0c;路上有检查站会导致部分货物无…

基于kubernetes组件初步部署k8s

基于k8s组件初步部署k8s kubernetes组件kubernetes简单化部署安装Master操作环境检查安装配置Containerd安装Containerd配置containerd启动containerd 配置Circtl安装配置Kubeadm安装Kubeadmkubeadm配置启动kubelet服务 拉取镜像初始化集群操作命令行 安装网络插件 Node操作Nod…

Dubbo分布式服务框架,springboot+dubbo+zookeeper

一Dubbo的简易介绍 1.Dubbo是什么&#xff1f; Dubbo是一个分布式服务框架&#xff0c;致力于提供高性能和透明化的RPC远程服务调用方案&#xff0c;以及SOA服务治理方案。 简单的说&#xff0c;dubbo就是个服务框架&#xff0c;如果没有分布式的需求&#xff0c;其实是不需…

N天爆肝数据库——MySQL(1)

数据库概念理解 数据库 DB 存储数据的仓库 数据库管理系统 DBMS 操纵和管理数据库的大型软件 SQL 操作关系型数据库的编程语言&#xff0c;定义了用一套操作关系型数据库同意标准 学习 SQL 的作用 SQL 是一门 ANSI 的标准计算机语言&#xff0c;用来访问和操作数据库系统。S…

在北京买房究竟需要多少钱?

无论是来北京前&#xff0c;还是来北京后&#xff0c;每每提起北京的房价&#xff0c;大家都会说出三个字「买不起」。 确实&#xff0c;北京房价非常贵&#xff0c;但是究竟「贵」到什么程度&#xff0c;我们却无法说出一个数。 几年前&#xff0c;我研三还没毕业时&#xf…

Linux高频常用指令汇总

目录 认识 Linux 目录结构 绝对路径&#xff1a;以根目录开头的, 称为绝对路径 相对路径&#xff1a;不是根目录开头的,称为相对路径 ls pwd cd mkdir touch cat echo rm cp mv vim编辑器 1、进入文件 2、进行编辑模式 3、保存退出 重要的几个热键[Tab],[ct…

SpringBoot中间件——封装限流器

背景 通常能知道一个系统服务在正产增速下流量大小&#xff0c;扩容与压测也是基于此。若有突发或者恶意攻击访问&#xff0c;都要将流量拦截在外。这部分功能不属于业务侧&#xff0c;它是通用非业务的共性需求&#xff0c;所以我们将共性抽取为限流中间件。 方案设计 图解&…