无法让scan.execCommand('undo')在浏览器中以相同的方式工作

时间:2013-04-25 22:21:35

标签: javascript cross-browser contenteditable execcommand

我有一些代码在文本框上实现上下文菜单,上下文菜单中有一个UndoRedo项,使用document.execCommand('undo')调用浏览器本机方法。 />
 此代码的功能与我在Chromium浏览器上的要求相同,但在FireFox和Opera上,结果不符合预期。

 我的期望是undo和redo将像输入元素的本机浏览器上下文菜单一样运行。结果是输入元素不会撤消和重做,但是设置了contenteditable属性的div元素会按预期运行。

所以我想知道这是其中一个浏览器中的错误,无论是Chromium还是FireFox / Opera,或者我是不是正确实现了代码?

以下代码给出了我所面临的问题的示例。感谢所有帮助。

<input contenteditable id="input" type="text"></input>
<div contenteditable id="div" class="inputLike" type="text"></div>
<button id="button1" type="button">Undo</button>
<button id="button2" type="button">Redo</button>

var input = document.getElementById("input"),
    button1 = document.getElementById("button1"),
    button2 = document.getElementById("button2"),
    div = document.getElementById("div");

console.log("Undo", document.queryCommandSupported("undo"));
console.log("Redo", document.queryCommandSupported("redo"));

function doUndo() {
    document.execCommand('undo', false, null);
}

function doRedo() {
    document.execCommand('redo', false, null);
}

button1.addEventListener("click", doUndo, false);
button2.addEventListener("click", doRedo, false);

jsfiddle

如果您想查看实际的上下文菜单代码,那么它也可以在jsfiddle上找到。

2 个答案:

答案 0 :(得分:2)

正如我在question中发现的那样,Firefox中的undoManager API工作正常。我查看了Tim Down发布的jsFiddle链接(http://jsfiddle.net/DULV4/1/),似乎有几个问题:

  • undoScope属性必须设置为true(内联或编程)。这样可以为该元素undoManager启用。
  • 您撤消的任何内容都必须首先由undoManager.transact()函数创建(尽管我想知道是否有任何方法可以将本机撤消堆栈合并到当前的undoManager的事务历史记录中)。

我对此只是一个新手,所以请理解我所说的一切,并查看有关使用它的所有信息https://dvcs.w3.org/hg/undomanager/raw-file/tip/undomanager.html

答案 1 :(得分:1)

我认为至少在Firefox中使用document.execCommand()是不可能的。您可以创建自己的撤消堆栈,或将来使用新的UndoManager APIimplemented in Firefox 20disabled by default)。

以下是使用input事件拍摄值和选择的快照来使用自己的撤消堆栈的示例。例如,您可以通过将连续的键入事件合并到单个撤消项中来改善这一点。浏览器与插入符号位置之间也存在一些不一致,但它只是一个概念证明。

http://jsfiddle.net/FMSsL/

使用新的DOM UndoManager API似乎很简单:如果我理解正确并且浏览器支持它,<input>元素将具有undoManager属性,这是一个{{1}的对象1}}和undo()方法,因此任务就像

一样简单
redo()

不幸的是,只有Firefox 20及更高版本支持document.getElementById("input").undoManager.undo(); API,默认情况下它已被禁用。即使启用它,即使我认为应该使用以下演示也不起作用,所以这个选项有点可行。

http://jsfiddle.net/DULV4/2/