如何与浏览器 control+z/control+y 交互以进行撤消/重做?
Posted
技术标签:
【中文标题】如何与浏览器 control+z/control+y 交互以进行撤消/重做?【英文标题】:How can I interact with browser control+z/control+y for undo/redo? 【发布时间】:2014-08-06 17:47:16 【问题描述】:我正在创建自己的编辑器,并且终于解决了我已经躲避了数周的撤消/重做问题。
我已经创建了用于存储和遍历自定义操作历史的基本框架,但我似乎无法在 contentEditable
区域中找到有关如何与 浏览器 历史交互的良好信息。
看https://github.com/jzaefferer/undo/blob/master/undo.js,还是没看出来这是怎么做到的。
我可以撤消/重做我的自定义操作,但我不知道如何利用浏览器的默认历史记录。
如果我要覆盖默认的control + (z | y),我是否必须添加所有原始功能?
更新:我在哪里可以找到有关浏览器如何处理这些撤消/重做操作的更多信息?
【问题讨论】:
你是指他们访问过的页面? 您没有必须这样做,只要确保您对删除部分默认功能会产生的可用性问题感到满意。 这与页面历史无关.. html5 contentEditable 历史.. 正在输入的文本,execCommand
等。@blgt 有没有办法让 2 简单地共存?如果我能找到有关其工作原理的资源,我会更好地了解可以做什么和不可以做什么。
我见过的大多数情况只是使用了浏览器内置的撤消/重做功能。为什么需要特殊功能来处理自定义操作?
7 年...没有答案(顺便说一句,问题是实际的)
【参考方案1】:
查看 contenteditable demo 的来源,以了解有关他如何将库附加到 div 的更多信息。
$(function()
var stack = new Undo.Stack(),
EditCommand = Undo.Command.extend(
constructor: function(textarea, oldValue, newValue)
this.textarea = textarea;
this.oldValue = oldValue;
this.newValue = newValue;
,
execute: function()
,
undo: function()
this.textarea.html(this.oldValue);
,
redo: function()
this.textarea.html(this.newValue);
);
stack.changed = function()
stackUI();
;
var undo = $(".undo"),
redo = $(".redo"),
dirty = $(".dirty");
function stackUI()
undo.attr("disabled", !stack.canUndo());
redo.attr("disabled", !stack.canRedo());
dirty.toggle(stack.dirty());
stackUI();
$(document.body).delegate(".undo, .redo, .save", "click", function()
var what = $(this).attr("class");
stack[what]();
return false;
);
var text = $("#text"),
startValue = text.html(),
timer;
$("#text").bind("keyup", function()
// a way too simple algorithm in place of single-character undo
clearTimeout(timer);
timer = setTimeout(function()
var newValue = text.html();
// ignore meta key presses
if (newValue != startValue)
// this could try and make a diff instead of storing snapshots
stack.execute(new EditCommand(text, startValue, newValue));
startValue = newValue;
, 250);
);
$(".bold").click(function()
document.execCommand("bold", false);
var newValue = text.html();
stack.execute(new EditCommand(text, startValue, newValue));
startValue = newValue;
);
// This is where he attaches the observer for undo / redo.
// For more information: https://***.com/questions/16006583/capturing-ctrlz-key-combination-in-javascript
$(document).keydown(function(event)
if (!event.metaKey || event.keyCode != 90)
return;
event.preventDefault();
if (event.shiftKey)
stack.canRedo() && stack.redo()
else
stack.canUndo() && stack.undo();
);
);
Capturing ctrl+z key combination in javascript
【讨论】:
【参考方案2】:使用它,但它只适用于<div contentEditable="true">
框。在 textarea 中,它一次撤消和重做所有文本,而不是像在 div 中那样逐字逐句。
<script language="JavaScript">
function Undo() document.execCommand("undo", false, null);
function Redo() document.execCommand("redo", false, null);
</script>
<div contentEditable="true" style="background-color:rgba(0,0,0,0.8); resize:none; width: 499px; height: 230px; border: 1px solid red;"></div>
<input type="button" onmouseup="Undo()" value="Undo" />
<input type="button" onmouseup="Redo()" value="Redo" />
【讨论】:
【参考方案3】:我不相信直接访问撤消缓冲区的内容,但您可以使用document.execCommand 触发撤消或重做。简单例子:
<html>
<head>
<style>
#box
width: 200px;
height: 100px;
background-color: grey;
</style>
</head>
<body>
<div id="box" contenteditable="true"></div>
<button id="undo">Undo</button>
<button id="redo">Redo</button>
<script>
var box = document.getElementById('box');
var undo = document.getElementById('undo');
var redo = document.getElementById('redo');
undo.addEventListener('click', function (ev)
document.execCommand('undo', false, null);
);
redo.addEventListener('click', function (ev)
document.execCommand('redo', false, null);
);
</script>
</body>
</html>
检查它是否为jsfiddle。
【讨论】:
这对我的情况没有帮助。我知道我可以为execCommand
函数执行此操作,但是诸如键入的文本之类的内容超出了此答案的范围。默认的撤消/重做不仅仅是粗体/取消粗体等。我只需要它做更多更多,并与我的自定义操作共存。看来我必须“破解”默认功能并完全覆盖它..
我认为你应该澄清一下你的问题。您的问题似乎是关于如何访问默认的撤消/重做功能,即使在覆盖典型的(ctrl-c/z)快捷方式时也是如此。如果您解释了您想要完成的工作,这将有所帮助。您需要的更多功能是什么?我认为这个问题有一个XY Problem。以上是关于如何与浏览器 control+z/control+y 交互以进行撤消/重做?的主要内容,如果未能解决你的问题,请参考以下文章
CORS“Access-Control-Allow-Origin”值如何暴露给浏览器?
打开浏览器就弹出“ 找到多个与名为“Home”的控制器匹配的类型。如果为此请求(“control
将 Cache-Control: max-age 与 ETag 一起使用时会发生啥?
如何在 Rails 环境中使用 Cache-Control: max-age Header 来控制 Varnish 和浏览器?