3

我有一些在文本框上实现上下文菜单的代码,上下文菜单是有一个UndoRedo项目,它通过使用来调用浏览器本机方法document.execCommand('undo')

此代码在基于 Chromium 的浏览器上运行,但在 FireFox 和 Opera 上,结果不如预期。

我的期望是撤消和重做将像输入元素的本机浏览器上下文菜单一样起作用。结果是输入元素不会撤消和重做,但是具有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上找到。

4

3 回答 3

3

我认为document.execCommand()至少在 Firefox 中是不可能的。您可以创建自己的撤消堆栈,或者将来使用新的UndoManager API在 Firefox 20 中实现默认禁用)。

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

http://jsfiddle.net/FMSsL/

使用新的 DOM UndoManager API 似乎很简单:如果我理解正确并且浏览器支持它,<input>元素就会有一个undoManager属性,它是一个带有undo()redo()方法的对象,所以任务很简单

document.getElementById("input").undoManager.undo();

不幸的是,只有 Firefox 20 及更高版本支持该UndoManagerAPI,并且默认情况下它被禁用。即使启用了它,即使我认为它应该,以下演示也不起作用,所以这个选项离可行还有一段路要走。

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

于 2013-04-26T09:40:22.723 回答
2

正如我从我提出的问题中发现的那样,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了解有关使用的所有信息它。

于 2013-05-05T01:05:12.347 回答
0

可以获取 UNDO 和 REDO 的历史

function check(){
if(document.queryCommandEnabled("undo"))
  {
    $('#undoResult').text("Undo is active");
    }else{
      $('#undoResult').text("Undo is not active");
  }
if(document.queryCommandEnabled("redo"))
  {
    $('#redoResult').text("Redo is active");
    }else{
      $('#redoResult').text("Redo is not active");
  }
  }
  $(document).on('keypress',function(e) {
      if(e.which == 13) {
        document.execCommand("insertLineBreak");
              return false;
      }
      });
  check();
div{
  border:1px solid black;
  height:100px;
}

button{
color:white;
background:black;
height:40px;
width:49%;
padding:1px;
text-align:center;
margin-top:10px;
}

p{
font-size:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div contenteditable="true">
</div>

<button onclick="document.execCommand('undo',false,null);check()" >Undo</button>

<button onclick="document.execCommand('redo',false,null); check()" >Redo</button>

<p id='undoResult'></p>
<p id='redoResult'></p>

于 2022-02-04T11:45:14.430 回答