在线记事本

打开就能写,停笔 300 毫秒自动存进本机浏览器;换标签页自动同步,随时导出 txt 或 md,全程不经过服务器。

已保存汉字 124 · 字符 230 · 行 11 · 占用 0.45 KB

使用方法

  1. 打开这个在线记事本,编辑区里已经预置了一段 11 行、124 个汉字的示例,直接选中改写就行。写完后什么都不用按:停笔 300 毫秒,右上角状态会从「保存中」变成「已保存」。
  2. 想立刻落盘而不等那 300 毫秒,按 Ctrl + Enter(macOS 用 Cmd + Enter)。裸 Enter 是换行,不会被抢去做保存——竖排写清单、写代码块都靠它。
  3. 状态条右侧实时给出汉字数、字符数、行数和 UTF-16 占用,边写边看篇幅,不用另开统计工具。
  4. 换页面前记得确认状态是「已保存」。若停在「保存中」就关掉,那一次修改不会写入。
  5. 点「导出 .txt」把全文存成纯文本;点「导出 .md」会在开头加一行 # 在线记事本 一级标题,其余原样。两个文件都按 UTF-8 编码。
  6. 点「清空」会弹一次确认:内容与本机存储一起删除,无法撤销,所以清空前建议先导出备份。点「载入示例」可随时把上面那段样例还原回来。

这个在线记事本能解决什么问题

一是临时中转。从一份文档里复制三段内容、来回对照着改,放在记事本里比反复切换窗口省事;刷新页面、甚至关掉浏览器再打开,内容还在。

二是多标签对照。同一篇材料要在一个标签页查资料、另一个标签页整理,两边改的都是同一份存储,storage 事件会把变更推给另一个标签页,不必手动复制粘贴。

三是不联网也能用。全文只写进本机浏览器的 localStorage,不发一个网络请求,也就没有「草稿被传到服务器」这类顾虑;断网状态下照样编辑和保存。

四是给写作定个近处的手感。开着字数统计写提纲、写待办、写会议速记,600 字的小目标有没有到一眼就能看见。

本页不做这些事:不做账号登录与云端同步(换电脑读不到),不做富文本排版与图片插入,不做版本历史与撤销回溯,也不加密内容——同一台电脑上能打开这个浏览器的人都能读到。要存敏感信息、需要口令保护,请用页面底部的「SecureNote 生成器」;要做多级要点与结构图,请用「在线思维导图工具」。

存储原理:localStorage 配额、300 毫秒防抖与 storage 事件

内容写在这里:localStorage.setItem('liuquan-zxjsb-note-v1', 文本)。它是 W3C Web Storage 规范定义的同步阻塞接口,按同源共享:同一个站点下的所有页面读写的是同一份数据,换一台电脑或换一个浏览器就读不到。数据没有过期时间,只有显式删除或用户清理浏览器数据才会消失。

配额约 5 MB 且按 UTF-16 计费。浏览器普遍按「每个 UTF-16 码元 2 字节」计费,而汉字落在基本平面、1 个字正好占 1 个码元、2 个字节。所以 5 MiB = 5242880 字节理论上能装 2621440 个汉字(约 262 万字),正文里说的「约 260 万字」就是这个数取整。补充平面字符要翻倍:一个 emoji 占 2 个码元、4 个字节,比一个汉字贵一倍。要注意各浏览器对「5 MB」的解析并不统一,Chrome 实测大约在 500 万码元附近才抛 QuotaExceededError,所以真正写入时一定要用 try / catch 兜住,而不是假定「没满 260 万字就一定能存」。

为什么不是每次输入都写。input 事件在高速输入时一秒能触发 20 次以上,而 localStorage 是同步阻塞的——每敲一个字就写一遍整个文本,大字符串下会明显掉帧,输入法也会发顿。300 毫秒防抖把这个过程改成:每次输入只重置一个定时器,停笔满 300 毫秒才真正写一次。写入次数从每秒 20 次降到大约 1~4 次,而代价只有 300 毫秒的延迟。裸 Enter 只是换行、不触发保存,也正是为了不打断连续输入。

多标签同步靠 storage 事件。当 A 标签页写入某个 key 时,同源的其他标签页会收到一个 storage 事件,带着 key、oldValue、newValue。关键细节:触发写入的那个标签页自己不会收到这个事件,所以不能靠它来更新本页的「已保存」状态——本页的状态由 setItem 成功后的返回值直接设置。本页在收到事件后会比对 newValue,与当前文本相同就忽略,避免自己触发的回声把光标顶乱。

导出用 Blob + ObjectURL,用完必须释放。下载不落地到服务器:把文本包成 new Blob([文本], { type:'text/plain;charset=utf-8' }),再用 URL.createObjectURL(blob) 拿到一个形如 blob:https://…/uuid 的临时地址挂到 <a download> 上点击。这个地址会一直把 Blob 钉在内存里,所以点击后必须调用 URL.revokeObjectURL(url) 释放,否则反复导出会让内存持续上涨。本页在下载后立刻撤销,正是这个原因。

完整示例(数值仅作演示)

示例内容就是编辑区里那段 11 行的样例文本,共 124 个汉字、230 个字符(码点与码元相等)、11 行,在本机占 460 字节(0.45 KB)——因为汉字在本页按 UTF-16 的 2 字节/码元计费,230 × 2 = 460。

同样一段内容换不同的规模,占用差别很大:一篇 1000 字短文占 1.95 KB,5 万字中篇占 97.66 KB,20 万字长篇占 390.63 KB,50 万字开始就该考虑分段存储了。下面这张表可以直接对照。

输入范围与存储规模对照表

下表按「每 1 个 UTF-16 码元 2 字节、配额 5 MiB」估算,用来判断某个体量的内容放进这个在线记事本会不会触顶。默认显示 12 行,点「加载更多」看完全部 18 行;点「下载 CSV」导出带 BOM 的表格文件,Excel 打开不乱码。

文本规模码元数UTF-16 占用占 5 MB 配额备注
一则待办200.04 KB0.0008%随手记一行
一条便签2000.39 KB0.0076%一段摘要
一篇短文1,0001.95 KB0.04%公众号短稿
会议纪要3,0005.86 KB0.11%半天会议记录
长篇笔记10,00019.53 KB0.38%万字长文
中篇小说50,00097.66 KB1.91%约 5 万字
长篇小说200,000390.63 KB7.63%约 20 万字
词库 / 字典500,000976.56 KB19.07%明显偏大
样本数据1,000,0001,953.13 KB38.15%已占近四成
上限一半1,310,7202,560.00 KB50.00%2.5 MB
安全线2,000,0003,906.25 KB76.29%建议封顶
理论上限2,621,4405,120.00 KB100.00%触顶即抛错

边界与精度说明

常见问题

内容到底存在哪里?换台电脑还能看到吗?

存在本机浏览器的 localStorage 里,键名是 liuquan-zxjsb-note-v1,属于这个站点的同源存储。换一台电脑、换一个浏览器、或者用无痕窗口打开,都读不到同一份数据;服务器上没有副本,因为本页根本不上传。

为什么粘贴大段文字时页面会卡一下?

因为 localStorage 是同步阻塞接口:写一个几万字的字符串时,主线程要等它写完才能继续处理界面,这一下就会体现为掉帧。本页用 300 毫秒防抖把写入合并成「停笔后一次」,能显著减少卡顿,但单次写入本身无法变成异步——这是接口的固有特性,不是本页的实现问题。

另一个标签页改了内容,本页会自动更新吗?

会,但只有「不是它自己」的改动才会触发。同源的其他标签页写入后,本页会收到 storage 事件并整段替换为最新文本,同时提示「已同步」。而发起写入的那个标签页收不到事件——这是 storage 事件的规范行为,所以本页的「已保存」状态是写入成功后直接设置的,不依赖事件。

为什么按 Enter 不保存,一定要按 Ctrl + Enter?

因为记事本里的 Enter 必须留给换行。写清单、写代码片段、写分行提纲都靠它,一旦被拿去当保存键,就再也打不出换行了。这是记事本类工具与普通单行输入框最大的交互差异,所以这里统一改成 Ctrl + Enter(macOS 用 Cmd + Enter)触发保存。

提示「保存失败」怎么办?

两种常见原因:一是内容超过约 5 MB 配额,页面会先算出当前占用并提示你先导出备份再删减;二是浏览器禁用了本地存储(无痕模式或隐私设置),此时写入会抛异常,页面会把异常名一并显示出来。不管哪种,第一件事都是点「导出 .txt」把文本落到本地文件,避免内容只存在于内存里。

清空以后还能恢复吗?

不能。localStorage.removeItem 没有回收站,删掉就没了,浏览器也不提供撤销。所以「清空」被做成两步:先点一次按钮会变成「再点一次确认清空」,再点一次才真正删除并同步清掉本机存储。保险做法是清空前先点「导出 .txt」,把内容存成本地文件。

导出的 .txt 和 .md 有什么区别?

只有一处不同:.md 会在最前面加一行 # 在线记事本 作为一级标题,其余原文一字不改;.txt 是原样的纯文本。两个文件都按 UTF-8 编码,用系统记事本、VS Code 或任何 Markdown 阅读器打开都不会乱码。

这个记事本有容量上限吗?超了会怎样?

有,约 5 MB / 源,折合约 262 万个汉字。写入前页面会先按字节数拦一道,超过就提示当前占用并拒绝本次写入,同时把状态标成「保存失败」;即使侥幸越过这道检查,setItem 抛出的 QuotaExceededError 也会被 try / catch 接住并显示具体错误名。无论哪种情况都不会静默丢内容,编辑区里的文字仍在,可以导出后再删减。

相关工具