首页 > 解决方案 > How to perform programmatic text input that supports both undo and redo?

问题描述

My current Chrome extension is supposed to programmatically insert text on user input. This works great, however, it mangles the undo/redo behavior of all text editors I've tried it on so far. So, the following routine:

  1. type some text
  2. insert some text programmatically
  3. type more text
  4. press ctrl-z thrice

does not always revert to a blank state. Very often it will get stuck somewhere in the middle. Its behaviour is mostly inconsistent.

Here's an MCVE of the content script:

function init() {
  var $input = document.getElementsByTagName("textarea")[0];
  if (!$input) {
    console.log("No input element found.");
    return true;
  }
  var $btn = document.createElement("button");
  $btn.innerHTML = "Click";
  $btn.addEventListener("click", function() {
    var caretPos = $input.selectionStart;
    $input.value = $input.value.substring(0, caretPos) + " test string " + $input.value.substring(caretPos);
  });

  $input.parentElement.insertBefore($btn, $input);

  return true;
}
window.addEventListener("load", init);
<div><textarea></textarea></div>

(I also bundled it as a Chrome extension in case you'd like that.)

I want the undo/redo to function perfectly in both textarea as well as contenteditable nodes. I also tried document.execCommand in both insertText and insertHTML modes without any success. I've looked at the other two related questions but they do not answer my query. (q1, q2)

What else can be a possible solution to this problem?

标签: javascriptgoogle-chrome-extension

解决方案


多亏了上面有用的评论,我的问题是在execCommandFacebook messenger box、tinymce 等预编程的奇怪编辑器上做的。他们可能有自己的自定义干扰。

在普通文本编辑器中,document.execCommand应该可以正常工作,并支持撤消/重做。像这样使用它:

document.execCommand('insertText', false, "text");
document.execCommand('insertHTML', false, "html");

推荐阅读