如何使用JavaScript将文本插入文本区域,而不破坏编辑历史?

如何使用JavaScript将文本插入文本区域,而不破坏编辑历史?,javascript,html,textarea,undo-redo,Javascript,Html,Textarea,Undo Redo,基本上,我想要的是,如果用户在文本区域中选择一些文本并按下ctrl+b,那么选择中的文本应该被星星包围 所以基本上我想要的是: 1) 文本区内容:“你好,这是一些文本” 2) 用户选择一些文本并按ctrl+b“hello this是一些文本”(假设粗体部分是一个文本选择) 3) 因此,我希望textarea内容为: “你好,这是一些*文本” 4) 如果用户按ctrl+z(或任何撤消操作),则 textarea内容应恢复为“你好,这是一些文本” 我尝试过和类似的方法,但问题是在对大多数浏览器执行撤

基本上,我想要的是,如果用户在文本区域中选择一些文本并按下ctrl+b,那么选择中的文本应该被星星包围

所以基本上我想要的是:

1) 文本区内容:“你好,这是一些文本”

2) 用户选择一些文本并按ctrl+b“hello this是一些文本”(假设粗体部分是一个文本选择)

3) 因此,我希望textarea内容为: “你好,这是一些*文本”

4) 如果用户按ctrl+z(或任何撤消操作),则 textarea内容应恢复为“你好,这是一些文本”

我尝试过和类似的方法,但问题是在对大多数浏览器执行撤消(ctrl+z)时,我希望文本返回到步骤1中的值。但事实并非如此。我知道stackoverflow在其编辑器中实现了自己的撤消重做功能。但我不希望说得那么复杂。 必须支持chrome和safari


我正在考虑的一种方法是定位光标并发出合成键事件。我不知道它是否能工作,也不知道它是否不会出现问题

我从以下代码中获得:您也可以检查它的工作示例。
尽管您可能需要实现自己的功能,如粗体、斜体等

函数iObject(){
这个,我,;
归还这个;
}
var myObject=new ioobject();
myObject.i=0;
var myObject2=新的ioobject();
myObject2.i=0;
store_text=新数组();
//存储\文本[0]存储初始文本区域值
存储_文本[0]=“”;
函数countclik(标记){
myObject.i++;
变量y=myObject.i;
var x=标记值;
存储_text[y]=x;
}
函数撤消(标记){
if((myObject2.i)1){
myObject2.i--;
}否则{
警报(“完成重做操作”);
}
var z=存储\文本长度;
z=z-myObject2.i;
if(存储_文本[z]){
tag.value=store_text[z];
}否则{
tag.value=store_text[0];
}
}


提供免费Java脚本
通过
更新版本 要在更改textarea的总值时保存用户历史记录,而不是:

textarea.value = newText;
使用:

在我的中端游戏装备上,字符串略多于4000个字符,大约需要~1秒,因此您必须确定这是否适用于您的用例

旧版本 也许您熟悉
execCommand
,不明白我们为什么不使用这个:

textarea.focus();
document.execCommand('selectAll',false);
document.execCommand('insertText',false,newText);
在Chromium上,
insertText
非常慢,尤其是对于较长的字符串。例如,超过4000个字符,在我的中型游戏公司上,更新版本中使用的相同字符串需要~10秒

不过它也保存了用户历史记录,并且在历史记录状态之间移动仍然是可以接受的速度(~0.5秒)

因为我会假设我在更新版本中明确地做了什么,而Chromium在后台做了什么,所以这样做是否有意义?不,但我想这就是铬今天的位置。如果旧版本变得更好,请在下面进行评论

一般说明 不幸的是,
execCommand
在Firefox的textarea元素中不起作用

在Chromium和Firefox中测试


如果我找到一个更快的解决方案(和/或在Firefox中运行的解决方案),我一定会与大家分享。

谢谢你的回答:)。但正如我在问题中提到的,我希望这样做而不必构建自己的撤销重做功能:)你可以使用诸如ckeditor之类的插件,我相信在添加功能时会减少很多工作:)有趣的是,如果你使用
insertHTML
而不是
insertText
,它跑得快多了。然而,如果任何东西都可以读作HTML,它将被删除。我会做进一步的测试。
textarea.focus();
document.execCommand('selectAll',false);
document.execCommand('insertText',false,newText);