知乎的答案编辑器是如何实现 撤销和前进 状态操作的?

知乎的答案编辑器 可以撤销输入,后悔了也可以前进,回到上一步。
关注者
9
被浏览
2,563

2 个回答

泻药

偶不知道啊

看着压缩后的代码像是用了

goog.editor.plugins.UndoRedo

的样子

不太熟悉知乎的编辑器, 但做过编辑器, 可提供思路.


一般都有个undoManager 或 historyManager 的对象管理一个栈.


# 自实现编辑Command

  1. 如果编辑的Command都是自实现且每个Command实现了do/redo(), undo(), 那么每次编辑操作, 会执行一个顶层Command的do(), 并将Command 入栈.
    • Undo 时, 执行最上面Command的undo()方法, 指针下移
    • Redo 时, 执行当前Command的 do/redo() 方法, 指针上移

# 非自实现Command

  1. 如果没有自实现Command, 可以使用contenteditable 特性自带的undo/redo管理. 缺点是: 每次编辑操作都必须使用document.execCommand() 来做修改, 不能直接修改内容DOM树.
  2. 如果没有自实现Command, 还想能够直接修改内容DOM树. 那么可以尝试定时保存内容(html格式)
    • 若内容有变化, 保存html内容和光标位置(Selection) -- 入栈. (这里涉及一个比较麻烦的问题, 即如何将Selection序列化)
    • Undo 时, 将保存的html内容和光标位置取出, 恢复到编辑器中, 指针下移
    • Redo 时, 指针上移, 将当前的html内容和光标位置取出, 恢复到编辑器中
  3. 有的编辑器使用打mark的方法 -- 个人没有研究过.

如果简单实现一个编辑器, 建议使用contenteditable特性自带的undo/redo管理. 因为:

  1. 编辑器坑比较多
  2. 自己填坑也未必填得好