纯html无法实现可编辑wiki,需结合contenteditable、localstorage和轻量js:双击编辑、自动保存、刷新不丢内容,支持目录锚点与基础格式操作,规避xss与覆盖风险。

怎么用纯 HTML 搭一个可读可编辑的 Wiki 页面
不能只靠 html 文件本身实现“编辑+保存”,必须引入轻量 JS 逻辑和浏览器本地存储能力。纯静态 HTML 只能展示,连“点一下就改文字”都做不到——因为没交互、没状态、没持久化。
真正实用的最小可行 Wiki 页面,是 HTML + localStorage + 内联编辑(contenteditable)三者组合。不依赖后端、不装 Node、不跑服务,双击就能改,刷新不丢内容。
-
contenteditable="true"让任意<div> 变成可编辑区域,但默认无样式反馈,需加 <code>outline: none和:focus边框 - 用
localStorage.setItem('wiki-content', el.innerHTML)在失去焦点(blur)时自动存档 - 页面加载时用
localStorage.getItem('wiki-content')回填,为空则设默认 Markdown 式文案(如<h2>简介</h2> <p>双击编辑本页...</p>) - 别用
document.write或直接.innerHTML = xxx赋值含 HTML 的字符串——XSS 风险高;简单场景下可用textContent+ 白名单标签过滤,或直接信任内部编辑内容 - 需要加粗?
document.execCommand('bold');插入链接?document.execCommand('createLink', false, 'https://example.com') - 渲染层完全由浏览器负责,不用引入
marked、remark等解析器,省掉 AST 转换、HTML 转义、脚本沙箱等一堆事 - 缺点也很明确:复制粘贴易带冗余
style和span;不能限制用户乱插<script></script>;历史版本得自己用localStorage做快照轮存(比如存 5 个wiki-content-v1到v5) - 规避方法:加时间戳校验。每次存前记录
lastSavedAt,读取时对比,若发现本地时间早于存储时间,弹提示“检测到其他窗口已更新,请刷新” - 不要把整页 HTML 当字符串存——提取关键区块,比如只存
article元素内的innerHTML,避免因页头页尾变动导致误覆盖 - 敏感内容别放这里。
localStorage是明文存在磁盘上的,任何同源 JS 都能读,不适合存密码、token、内部 API 地址
为什么不用 Markdown 渲染而选 contenteditable
想支持“所见即所得”的快速编辑,contenteditable 是目前浏览器原生唯一靠谱方案。Markdown 编辑器(如 simplemde、toast-ui-editor)功能强,但体积大、配置碎、移动端光标错位常见。
真实 Wiki 使用场景里,80% 的编辑是改标题、补句子、加链接——这些 contenteditable 一行 document.execCommand('insertHTML', false, '<a href="..."> 就能搞定,比学 Markdown 语法快得多。</a>
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
localStorage 存 Wiki 内容会丢数据吗
会,但只在极少数情况:用户手动清空浏览器缓存、使用无痕模式、或触发浏览器存储配额限制(通常 5–10MB,纯文本 Wiki 几万字都远不到)。
更现实的风险是覆盖写入——比如两个标签页同时打开同一 Wiki 页面,A 页改完存了,B 页再改再存,A 的修改就被无声覆盖。这不是 localStorage 的 bug,而是它没提供并发控制机制。
如何让 Wiki 页面支持简单目录和锚点跳转
不需要 JS 解析标题生成 TOC,用原生 HTML5 <details><summary></summary></details> + CSS 就能做出可折叠目录,且零 JS 依赖。
<details><summary>目录</summary><nav aria-label="页面导航"><ul>
<li><a href="#section-1">安装步骤</a></li>
<li><a href="#section-2">常见问题</a></li>
</ul></nav></details>
对应正文用 <h2 id="section-1">安装步骤</h2> 即可。注意:id 值必须合法(不能含空格、中文、特殊符号),建议用 textContent.toLowerCase().replace(/[^a-z0-9]+/g, '-') 自动生成。
- 双击编辑时,
id不应被用户随意删改,否则锚点失效。可在 JS 中监听input事件,对h1–h6标签自动同步id属性 - 滚动到锚点后,浏览器默认会把元素顶到视口顶部,遮住标题栏。加一句
scroll-margin-top: 64px(假设导航栏高 64px)即可修正 - 不要用
location.hash手动监听跳转做高亮——现代浏览器原生支持:target伪类,h2:target { background-color: #fffbcc; }一行就搞定
<div>,Shift+Enter 插 <code><br>,但 Safari 和 Firefox 对 execCommand 支持度不一。如果团队里有人用 iPad 编辑 Wiki,务必真机测一遍回车和粘贴。










