是否可以使用 javascript 编辑文本输入并添加到撤消堆栈

Is it possible to edit a text input with javascript and add to the Undo stack?

本文关键字:添加 撤消 堆栈 输入 文本 可以使 javascript 编辑 是否      更新时间:2023-09-26

有没有办法使用 javascript 编辑inputtextarea的内容,并可以使用浏览器的"撤消"命令(例如 ctrl-Z )撤消该更改?

我正在尝试将一个字符串(例如"Foo {0} bar")插入到选择的值中,如果用户选择了范围,则所选范围将插入到字符串中以代替"{0}"。

例如,如果文本区域包含"示例 1 2 3",并且光标位于"示例 1|2 3",则函数会将值更改为"示例 1Foo blah bar 2 3"(在这种情况下valueIfNothingSelected为"blah")。如果选择了范围"1 2",则该函数会将值更改为"示例 Foo 1 2 bar 3"。

在Chrome中,我

测试了此功能,它完成了应有的操作,但是我无法撤消更改 undo .

function insertTextAtCursor(text, valueIfNothingSelected) {
    var field = $('textarea[name="task_log_description"]')[0];
    var startPos = field.selectionStart;
    var endPos = field.selectionEnd;
    var processedText;
    if (startPos == endPos) {
        processedText = text.replace('{0}', valueIfNothingSelected);
        field.value = field.value.substring(0, startPos) + processedText + field.value.substring(endPos, field.value.length);
        field.selectionStart = startPos + text.indexOf('{0}');
        field.selectionEnd = field.selectionStart + valueIfNothingSelected.length;
    } else {
        var selectedText = field.value.substring(startPos, endPos);
        processedText = text.replace('{0}', selectedText);
        field.value = field.value.substring(0, startPos) + processedText + field.value.substring(endPos, field.value.length);
        field.selectionStart = startPos + text.indexOf('{0}');
        field.selectionEnd = field.selectionStart + selectedText.length;
    }
    field.focus();
}

我找到了一个适用于 https://stackoverflow.com/a/10345596/1021426 的解决方案

通过替换"字段值 = ..."行与:

document.execCommand("insertText", false, processedText);

。并将"field.focus()"移到该行之前,我能够实现我想要的撤消/重做功能。

编辑:Firefox现在也支持execCommand。你只需要那个。

<小时 />

这是一个在Firefox中也可以使用的解决方案,它是性能最高的解决方案,并且除了Firefox之外的任何地方都提供撤消功能(在本地是不可能的)

// Solution
function insertText(textarea, text) {
    // https://stackoverflow.com/a/55174561/288906
    if (!document.execCommand('insertText', false, text)) {
        textarea.setRangeText(text);
    }
}
// Demo code to add text on click
const textarea = document.querySelector('textarea');
textarea.onclick = () => insertText(
  textarea,
  '@'
);
<textarea>Click in here to add text</textarea>

我还将其打包为 npm 模块,提高了浏览器之间的一致性并添加了"插入"、"替换"、"搜索和替换"等实用程序

下面是替换<textarea>内容而不仅仅是插入的代码。

function setValueAndUpdateUndoStack(textarea, text) {
    // Must select all, so that the old text is deleted.
    textarea.focus();
    textarea.select();
    
    // https://stackoverflow.com/a/55174561/3480193
    if ( ! document.execCommand('insertText', false, text) ) {
        textarea.setRangeText(text);
    }
}