Javascript 实现撤销
我正在创建一个地图编辑web应用程序,我们可以在其中创建和编辑多段线、多边形等。我在网上查找有关撤消实现的信息时遇到一些困难,我发现有人抱怨“我们需要撤消”和“这是我使用闭包的命令模式”,但我认为在这和完整的撤消/重做界面之间有相当多的路要走 所以,以下是我的问题(我认为这是维基的好候选):Javascript 实现撤销,javascript,user-interface,dom-events,undo,Javascript,User Interface,Dom Events,Undo,我正在创建一个地图编辑web应用程序,我们可以在其中创建和编辑多段线、多边形等。我在网上查找有关撤消实现的信息时遇到一些困难,我发现有人抱怨“我们需要撤消”和“这是我使用闭包的命令模式”,但我认为在这和完整的撤消/重做界面之间有相当多的路要走 所以,以下是我的问题(我认为这是维基的好候选): 我应该管理堆栈,还是有办法将命令发送到浏览器的堆栈?(以及如何处理本机命令,如本例中textifields中的文本编辑) 当某些命令是浏览器本机命令时,如何处理“命令压缩”(命令分组) 如何检测撤消(ct
- 我应该管理堆栈,还是有办法将命令发送到浏览器的堆栈?(以及如何处理本机命令,如本例中textifields中的文本编辑)
- 当某些命令是浏览器本机命令时,如何处理“命令压缩”(命令分组)
- 如何检测撤消(ctrl+z)按键
- 如果我注册了一个keyup事件,我如何决定是否阻止默认
- 如果没有,我可以在某个地方注册一些事件处理程序吗
- 用户不习惯在web上撤消,我如何“训练”他们在我的应用程序上浏览/撤消
- 卡布奇诺的自动撤销支持的工作方式是告诉撤销管理器应该撤销哪些属性。例如,假设您正在管理学生的记录,您可以执行以下操作:
[theUndoManager observeChangesForKeyPath:@"firstName" ofObject:theStudent];
[theUndoManager observeChangesForKeyPath:@"lastName" ofObject:theStudent];
现在,不管学生姓名在UI中如何更改,点击“撤消”将自动将其恢复。Cappuccino还自动处理同一运行循环中的合并更改,当撤消堆栈上有项目时,将文档标记为“脏”(需要保存),等等(换句话说,以上就是支持撤消所需的全部操作)
另一个例子是,如果您想使学生的添加和删除可撤消,您可以执行以下操作:
[theUndoManager observeChangesForKeyPath:@"students" ofObject:theClass];
由于“students”是类中的一个学生数组,因此将跟踪此数组中的添加和删除 您需要具有创建和删除对象的功能。然后将这些函数传递给撤消管理器。请参阅my javascript undo manager的演示文件: 演示代码显示画布,但代码是不可知的 它不包含键绑定,但可以帮助您完成第一步
我自己在一个web应用程序中使用了这个按钮,该应用程序的“保存”旁边有“撤消”和“重做”按钮。下面是一个使用敲除JS的N级撤消示例:
(函数(){
//当前状态可能来自服务器,例如这里的硬编码
var currentState=JSON.stringify({
名字:“保罗”,
姓氏:'Tyng',
文本:“文本”
})
,undoStack=[]//这表示JSON格式的数据的所有以前的状态
PrimeOnUndo= Falth//Frand指示在撤消操作的中间,当重置属性时跳过推到undoStad
,viewModel=ko.mapping.fromJSON(currentState);//用可观测值丰富状态
//这将创建一个订阅了所有可观察项的从属可观察项
//在视图中(toJS只是遍历所有属性的简写)
//然后订阅依赖的可观察对象以推送状态历史
ko.dependentToServable(函数(){
ko.toJS(viewModel);//订阅所有属性
},viewModel)。订阅(函数(){
如果(!performingUndo){
undoStack.push(当前状态);
currentState=ko.mapping.toJSON(viewModel);
}
});
//从undoStack中弹出状态历史记录,如果它是第一个条目,只需检索它即可
window.undo=函数(){
performingUndo=true;
如果(undoStack.length>1)
{
currentState=undoStack.pop();
fromJSON(currentState,{},viewModel);
}
否则{
currentState=undoStack[0];
fromJSON(undoStack[0],{},viewModel);
}
performingUndo=false;
};
应用绑定(视图模型);
})();代码>
撤消
撤消什么?浏览器中的输入字段已使用ctrl-z撤消。你需要撤销什么?提交?我的上下文是创建地图,但我想打开一点主题。谢谢,这很有趣,但是你如何在浏览器中与本机的撤消/重做集成?卡布奇诺只是处理这个问题--它会自动将它直接绑定到mac上的cmd-z,以及windows上的相应键绑定等。它应该“正常工作”我的目标不是盲目地使用卡布奇诺,我正在为一个不使用卡布奇诺的应用程序创建一个ando系统。我想知道你以前是怎么做的。但是框架代码真的很难阅读和理解。我不确定我是否理解——你是说你正在尝试实现类似卡布奇诺的撤销功能,但在一个不使用卡布奇诺的应用程序中?我不是要求任何人为我写代码,恰恰相反,我希望每个开发人员都能在一个地方使用自然语言信息来编写自己的代码。如果我单独问每一个问题,我会从饥肠辘辘的业力大军那里得到聪明的答案,这正是我不想要的。我认为我真正的问题是这个问题的位置不对(开放,没有直接的简短聪明的答案),但我不知道有哪一个网站更适合这个问题。它远远不足以管理暂时的编辑器状态(比如只绘制了多段线的一个点,还没有绘制第二个点),或者需要撤消堆栈压缩的连续编辑操作(颜色编辑器、滑块)。实际上,一种通用方法在这种情况下不起作用。对于连续操作,您可以选择只存储最终结果。问题是检测“最终结果”就像直接绑定到滑块的属性一样(因此用户可以立即对其操作进行反馈),您不知道他何时完成了滑块的摆弄。你可以试着用时间来推断它(2秒而不拨动滑块意味着他已经完成了),但要想正确地推断它是很困难的,因为某些事件(释放鼠标按钮)是开启的