如何在javascript中为自定义撤销堆栈高效地存储(小)html更新?

如何在javascript中为自定义撤销堆栈高效地存储(小)html更新?,javascript,undo-redo,Javascript,Undo Redo,我正在使用contenteditable构建一个CMS(与示例相当)。我正在修补ctrl+z/ctrl+y(undo/redo),因为有些命令无法在本机document.execCommand中执行,因此不会在本机undo堆栈中结束 因此,我想自己实现一个节省空间的撤销堆栈。由于这样一个堆栈中的条目在html上只有很小的差异(至少在大多数情况下是如此),因此使用某种delta/diff编码进行存储似乎是合乎逻辑的 是否有任何东西(javascript)可以很好地覆盖这个用例?或者,还有其他/更好

我正在使用
contenteditable
构建一个CMS(与示例相当)。我正在修补ctrl+z/ctrl+y(undo/redo),因为有些命令无法在本机
document.execCommand
中执行,因此不会在本机undo堆栈中结束

因此,我想自己实现一个节省空间的撤销堆栈。由于这样一个堆栈中的条目在html上只有很小的差异(至少在大多数情况下是如此),因此使用某种delta/diff编码进行存储似乎是合乎逻辑的


是否有任何东西(javascript)可以很好地覆盖这个用例?或者,还有其他/更好的方法可以做到这一点?

在您的实现中要包括以下几点:

  • 保存积分
  • 储藏
  • 检索
为了便于说明,我将使用一个撤消按钮、一个保存按钮和一个文本字段

每次更改文本字段时,可以使用间隔/计时器自动保存更改;或者,您可以依靠“保存”按钮显式创建保存点

计时器实现将当前文本与上一个快照进行比较。如果文本已更改且经过足够的时间,则会创建一个保存点。您可以使用onkeyup事件触发自动保存

下一点是存储。如果间歇变化不必持续,可以使用内存存储;或者只是JavaScript函数。将“history”对象附加到DOM元素。在本例中,使用textarea对象

<button onclick="undo();">Undo</button>
<textarea id="text" onkeyup="autosave()"></textarea>

<script>
function autosave(){
  var text=document.getElementById('text');
  var date=new Date(); var now=date.getTime();
  if (text.lastsaved==null) text.lastsaved=now;
  if (now-text.lastsaved<5000) return; //ignore changes within 5 seconds

  if (text.savetimer) clearTimeout(text.savetimer);
  text.savetimer=setTimeout(function(){
    if (!text.undohist) text.undohist=[];
    text.undohist.push(text.value); //save a snapshot
    text.lastsaved=now;
  }, 300); //if keys are continuously pressed, wait until it "settles down"
}

function undo(){
  var text=document.getElementById('text');
  var date=new Date(); var now=date.getTime();

  if (!text.undohist) return; //cannot undo any more

  if (text.undohist.length==0) return;

  text.value=text.undohist.pop();
  text.lastupdated=now;
}
</script>
Undo
函数autosave(){
var text=document.getElementById('text');
var date=new date();var now=date.getTime();
如果(text.lastsaved==null)text.lastsaved=now;

如果(now-text.lastsavednicely这么快就被砍掉了:)实际上,我更关心的是堆栈的节省空间的存储,但我喜欢您简单的实现。也许我现在不应该关心如何区分,而只需要在每个保存点上逐字存储内容。顺便说一句,我会在每个鼠标上都有保存点单击一个可编辑的图标(即:鼠标单击时保存更改,表示“已完成写入”),这就是本机重做对contenteditables的工作方式(至少在chrome中)。以及CMS对内容采取的其他特殊操作。谢谢。我还对存储使用情况感到好奇,不知道您存储的信息类型。您可能有一个最大撤消限制,或者“归档”真正的旧撤消(以及最近的撤消)使用持久性存储。这可能会使应用程序更具可扩展性,同时更轻。