Ins/Del 标签仅为语义容器,不触发编辑行为;需用 JavaScript 配合 MutationObserver 监听 DOM 变更、keydown 拦截编辑操作,并手动管理 data-author 等属性,才能实现可靠变更追踪。

Ins 和 Del 标签本身不触发编辑器行为,它们只是语义容器;想在编辑器中实现可交互的变更追踪,必须配合 JavaScript 操作 DOM 节点,而非依赖标签自动生效。
Ins/Del 标签在编辑器里不会自动高亮或可编辑
浏览器渲染 <ins> 时默认加下划线、<del> 加删除线,但这是纯样式表现,不携带“是否被接受/拒绝”状态。编辑器(如 contenteditable 元素)中直接插入这些标签,用户仍可随意删改、光标可自由进出,没有任何保护或拦截逻辑。
- 常见错误现象:
document.execCommand已废弃,且无法识别<ins>/<del>的语义边界,导致撤销/重做后标签丢失 - 真实使用场景:协同编辑(如多人修改同一段落)、审阅模式(类似 Word 的修订视图)、Git 式 diff 渲染
- 关键参数差异:
data-author、data-timestamp等自定义属性需手动添加,HTML 标准不定义这些字段
用 MutationObserver 监听并标准化 Ins/Del 插入位置
用户在 contenteditable 区域中粘贴或输入时,原生行为可能把 <ins> 套在文本节点外、嵌套错乱,甚至生成 <span style="text-decoration:underline"> 这类伪语义结构。必须用 MutationObserver 拦截并归一化。
- 观察
childList和characterData类型变更,过滤出含<ins>或<del>的新增节点 - 对插入的文本节点,用
Range和getSelection()判断光标是否落在变更范围内,决定是否允许编辑 - 避免直接
innerHTML = ...替换,否则会清空已绑定的事件监听器和数据属性
Del 标签不能阻止用户恢复删除内容
<del> 不是“锁定删除”,它只是标记某段文本曾被删去。用户仍可选中它、按退格键清除标签、或粘贴新内容覆盖——这会破坏变更历史的完整性。
立即学习“前端免费学习笔记(深入)”;
- 必须拦截
keydown事件,对Backspace和Delete键判断光标前后是否紧邻<del>边界 - 若光标位于
<del>开始处,应阻止默认行为,并弹出确认:“要恢复这段删除内容吗?” - 性能影响:频繁监听
keydown需节流,尤其在长文档中,否则滚动或输入会卡顿 - 兼容性注意:Safari 对
contenteditable中<del>的getBoundingClientRect()返回值不稳定,建议用Range.getClientRects()
真正难的不是插入 <ins> 或 <del>,而是让它们在编辑过程中始终可识别、可响应、不被意外破坏——这要求你把每个光标移动、每次粘贴、每回撤销都当作一次 DOM 协议协商来处理。



















