跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

HTML中实现Markdown实时预览编辑器的基本结构与思路

textarea是唯一可信输入源,必须与纯渲染div#preview同级共父、禁用contenteditable;实时更新需监听input事件并防抖,输出前须用DOMPurify白名单过滤,布局避坑height:100%。 HTML结构必须用
textarea
+
div
组合 不能用
contenteditable
或富文本编辑器替代
textarea
——它会导致光标错位、选区丢失、换行符处理异常,尤其在移动端。预览区必须是纯
div
,且不能设
contenteditable="true"
,否则用户可能误操作破坏渲染结果。 常见错误现象:用
div
模拟编辑区后,复制粘贴 Markdown 时格式全乱;或预览区被用户双击编辑,导致 HTML 源码泄露。
textarea
负责接收原始 Markdown 文本,保持纯文本语义
div#preview
只做渲染容器,不响应任何用户输入事件 两者必须同级包裹在同一个父容器中,避免 flex 或 grid 布局错位引发高度计算偏差 实时更新必须监听
input
事件而非
change
change
只在失焦时触发,完全不符合“实时”要求;而
input
能捕获所有输入行为(键盘、粘贴、拖放、剪贴板插入),是唯一可靠选择。 但要注意:直接在
input
回调里调用
marked.parse()
并写入
innerHTML
,会在长文档下造成明显卡顿。实测 300 行 Markdown 连续输入时,帧率可跌至 10fps 以下。 立即学习 “ 前端免费学习笔记(深入) ”; 必须加防抖,延迟 200–300ms 再执行解析(
setTimeout
requestIdleCallback
) 避免每次全量重绘:对超长文档,可只在内容长度变化超过 50 字符时才触发解析 不要在
input
里调用
focus()
setSelectionRange()
,会打断用户输入流 解析后 HTML 必须用
DOMPurify.sanitize()
过滤 直接把
marked.parse()
结果赋给
innerHTML
等于主动打开 XSS 入口。Markdown 允许内联 HTML,而
marked
默认开启
dangerouslyAllowHtml: true
(v4+ 版本),这意味着
会被原样执行。 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 哪怕你确认用户全是内部人员,也不能跳过净化——历史教训是:某次调试时临时加了
console.log(rawInput)
,结果日志里混入了恶意 payload,被前端监控系统误判为攻击流量。 必须引入
DOMPurify
,调用
DOMPurify.sanitize(html)
后再写入
div#preview
不要依赖
marked
自带的
sanitize
选项(已废弃且不可靠) 如果需要保留
,需显式配置
ALLOWED_TAGS
白名单 CSS布局要避开
height: 100%
陷阱 很多教程直接写
#preview { height: 100% }
,结果在 Safari 或 iOS WebView 中预览区高度塌陷为 0。根本原因是:百分比高度依赖父元素有明确高度,而
body
在无 DOCTYPE 或未设
height: 100vh
时,计算链会中断。 更隐蔽的问题是:当页面有顶部工具栏或 footer 时,
100%
会撑满整个视口,导致预览区溢出滚动条嵌套,用户拉到底部后无法看到最后几行。 推荐用
calc(100vh - Xpx)
,X 是固定顶部区域高度(如工具栏+padding) 编辑区和预览区必须共用同一父容器,并设
display: flex; flex-direction: column
grid
,确保高度分配可控 移动端需加
@media (max-width: 768px) { flex-direction: column; }
,否则左右分栏在小屏上直接错位 关键点其实就一个:
textarea
是唯一可信输入源,其余所有渲染、布局、安全控制都得围着它转。任何试图“优化体验”而绕过它的设计,最后都会在光标、粘贴、移动端或 XSS 上栽跟头。

相关文章