How to insert text into a textarea using JavaScript without messing up edit history?

html, javascript, textarea, undo-redo

Solution

Updated Version

To save user history when changing a textarea's overall value, instead of:

textarea.value = newText;

Use:

textarea.focus();
document.execCommand('selectAll',false);

var el = document.createElement('p');
el.innerText = newText;

document.execCommand('insertHTML',false,el.innerHTML);

It takes about ~1 second on my mid-end gaming rig with a string a little over 4,000 characters, so you'll have to figure out if that's acceptable for your use case.

Old Version

Maybe you're familiar with `execCommand` and wonder why we don't just use this:

textarea.focus();
document.execCommand('selectAll',false);
document.execCommand('insertText',false,newText);

On Chromium `insertText` is extremely slow, especially for longer strings. For an example over 4,000 characters, on my mid-gaming compy the same string as used in the Updated Version takes ~10 seconds.

It does save user history too though, and moving between history states is still an acceptable speed (~0.5 seconds).

Does it make sense that this is slower, since I would assume what I'm doing explicitly in the Updated Version Chromium's doing in the background anyway? No. But this is where Chromium's at today, I guess. Comment below if the Old Version becomes better.

General Notes

Unfortunately, `execCommand` doesn't work inside of textarea elements in Firefox. This may be fixed in an upcoming version.

Tested in Chromium and Firefox.

If I find a still faster solution (and/or one that works in Firefox), I will definitely share it.

Problem

Basically what i want is if a user selects some text in a textarea and presses ctrl + b then the text within the selection should be surrounded by stars. so basically what I want is : 1) textarea content : "hello this is some text" 2) user selects some text and presses ctrl + b "hello this is some text" (assume the bolded part is a text selection) 3) so I want the textarea content to be : "hello this *is some* text" 4) and if the user presses ctrl + z(or whatever the undo action) the textarea content should go back to being "hello this is some text" I have tried How can i use javascript to insert text into a textarea? and Insert text into textarea at cursor position (Javascript) and similar but the issue is that on doing undo (ctrl + z) for most browsers I expect the text to go back to go to the value in step 1. but this does not happen. I understand stackoverflow implements own undo redo functionality in its editor. but I was hoping not to go to that much complexity. Have to support chrome and safari An approach I am thinking about would be to position the cursor and issue a synthetic key event. I don't know if it will work and if it would be free of issues

Original source

Related problems