从textarea.my看零依赖Web应用设计:一个HTML文件如何实现完整文本编辑器的终极拆解
【免费下载链接】textareaA minimalist text editor that lives in URL项目地址: https://gitcode.com/gh_mirrors/texta/textarea
textarea(textarea.my)是一个零依赖的纯 HTML 文本编辑器:没有后端、没有数据库、没有 npm 包,整个应用就是 index.html 一个约 25KB 的文件,你写的所有文字都会被 deflate 压缩后直接存进 URL 哈希——复制链接,就完成了一次"分享"。今天就从新手视角,把这个单文件文本编辑器从输入、存储、渲染到部署完整拆开来看。
📦 为什么说它是"零依赖"?先看仓库文件清单
打开仓库,你只会看到寥寥几个文件:
| 文件 | 职责 | 大小 |
|---|---|---|
| index.html | 应用全部:HTML + CSS + JS 三合一 | ≈ 25 KB |
| sw.js | Service Worker,离线缓存页面 | < 1 KB |
| manifest.json | PWA 清单,支持"安装到主屏幕" | < 1 KB |
| 404.html | 手写 404 页面,同样是零依赖风格 | ≈ 1.2 KB |
| deploy.yaml | 推送到 master 自动部署到 Cloudflare Pages | ≈ 0.5 KB |
没有package.json、没有node_modules、没有构建脚本、没有框架。这正是"零依赖 Web 应用设计"的终极形态:静态托管一切搞定,打开就能用,断网也能开。
✍️ 编辑器本体:一行 contenteditable 定义输入体验
传统文本编辑器(如 Monaco、CodeMirror)动辄几百 KB。而 textarea 的编辑区只是一个带属性的标签(见 index.html#L265):
<article contenteditable="plaintext-only" spellcheck autofocus>
contenteditable="plaintext-only"是浏览器原生能力:用户可以随意输入粘贴,但页面里永远只保留纯文本,不会混入 HTML 格式——这就是它既能当"所见即所得"又无需富文本库的关键。光标、选区、输入法全部交给浏览器原生实现,一行代码省下几百个函数。
🎨 零依赖 Markdown 高亮:正则驱动的纯文本渲染
纯文本输入 + 轻量渲染,是 textarea 最巧妙的地方。它内置了一个约 70 行的手写 Markdown 解析器 parseMarkdown,仅用正则识别:
- 一级到六级标题(
#到######) - 行内代码、代码块(``` 与 ~~~ 两种围栏)
- 加粗、斜体、删除线
- URL 自动转成可点击链接
它的思路非常朴素:遍历文本,对每个位置依次尝试一组正则匹配器,命中就套上对应的 CSS 类,没命中就跳过下一个特殊字符。没有 AST、没有依赖、不会把用户输入"弄丢"——存进 URL 的始终是原始纯文本,样式只是展示层。
⏪ 自制撤销/重做:不依赖浏览器原生历史栈
由于高亮会不断重排 DOM,浏览器原生的撤销栈就不可靠了。textarea 用 Editor 函数手写了一个撤销历史:
- 每次有意义的按键输入前,把当前 HTML 和光标位置存入历史数组(最多 1 万条记录)
- 撤销/重做时恢复快照,并精确还原光标位置
- 连续输入做了 300ms 防抖合并,历史不会爆炸
约 250 行代码,实现了"不丢光标"的专业级编辑体验——这是新手理解"编辑器难在哪里"的最好教材。
🔗 文本如何"住进"URL:deflate 压缩 + Base64URL
这是整个项目最有意思的设计:URL 哈希即数据库。
- 输入防抖 500ms 后触发保存(index.html#L307)
- 全文本经浏览器原生 [CompressionStream('deflate-raw')] 压缩(index.html#L361-L379)
- 压缩结果转成 Base64URL 字符集(URL 安全,无需再编码)
history.replaceState静默更新地址栏
于是"分享笔记"没有任何按钮逻辑——地址栏本身就是分享链接。打开带哈希的链接时,hashchange事件触发解压回填,整条链路同样只用了原生 API,零第三方压缩库。
🌙 进阶玩法:标题、主题与"文档即网页"
textarea 藏了不少让普通用户惊喜的细节:
- 自定义页签标题:文档第一行以
# 标题开头时,浏览器标签页标题自动变成它(updateTitle) - CSS 皮肤也能分享:在 DevTools 里给
<article>加的style属性,会被 MutationObserver 捕获并一并压缩进 URL(index.html#L314) - 一键导出静态网页:
Ctrl+S把当前文档连同全部样式克隆成一个独立的 HTML 文件下载(downloadHTML) - 暗色模式零成本:CSS 变量 +
prefers-color-scheme,跟随系统切换(index.html#L26-L32)
📲 PWA 与部署:离线可用的最后两块拼图
- sw.js 用约 35 行实现"缓存优先"策略:安装时把首页存入 Cache Storage,断网时照样能打开编辑器
- manifest.json 让它可以像原生 App 一样安装到手机主屏幕
- 部署更是极简:deploy.yaml 一条 wrangler 命令把整个目录推到 Cloudflare Pages,连 Node 环境都不需要
一个完整的可离线使用的 PWA,仓库总代码量不到 1000 行(含样式)。
📋 新手能带走的"零依赖 Web 设计"清单
- 能用原生 API 就不要引库:CompressionStream、contenteditable、Blob、File System Access 都是浏览器白送的
- 把 URL 当存储:无状态、天然分享、天然备份,适合笔记类轻应用
- 存原始数据,渲染只做展示:输入永远纯文本,高亮层随存随算,怎么改都不丢数据
- 小 UI 用防抖合并:500ms 保存、300ms 历史、30ms 高亮,三个不同节奏各管一段
- PWA 三件套收尾:Service Worker + manifest + 静态托管,离线能力成本极低
🚀 如何获取源码本地运行
仓库是纯静态站点,克隆后直接用任意静态服务器(甚至python3 -m http.server)打开 index.html 即可体验:
git clone https://gitcode.com/gh_mirrors/texta/textarea cd textarea更多使用说明见 README.md,项目基于 MIT 协议 开源,可自由学习、二次开发。
【免费下载链接】textareaA minimalist text editor that lives in URL项目地址: https://gitcode.com/gh_mirrors/texta/textarea
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考