最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to enable Ctrl + Z when you change an input text dynamically with React? - Stack Overflow

programmeradmin4浏览0评论

I'm trying to create a simple React markdown editor.

The ponent is pletely controlled. The problem is: If the user selects abc in the textarea and clicks the B button, I need to call onchange() with **abc**. I need to surround the text with these asterisks.

This difference between what I pass on the onchange() and what the user has actually typed causes the textarea history to bee inconsistent. Ctrl + Z doesn't work anymore.

Demo. [EDIT: This demo has the fix implemented. It's not as it was when I asked the question]

How can I trigger onchange() on React with an arbitrary text and keep the Ctrl + Z consistent?

I'm trying to create a simple React markdown editor.

The ponent is pletely controlled. The problem is: If the user selects abc in the textarea and clicks the B button, I need to call onchange() with **abc**. I need to surround the text with these asterisks.

This difference between what I pass on the onchange() and what the user has actually typed causes the textarea history to bee inconsistent. Ctrl + Z doesn't work anymore.

Demo. [EDIT: This demo has the fix implemented. It's not as it was when I asked the question]

How can I trigger onchange() on React with an arbitrary text and keep the Ctrl + Z consistent?

Share Improve this question edited Dec 22, 2016 at 1:03 Andre Pena asked Dec 21, 2016 at 23:23 Andre PenaAndre Pena 59.5k53 gold badges210 silver badges257 bronze badges 2
  • 1 There's a discussion around undo/redo stack which gives a bit of insight into how your case might be implemented. The idea would be to suppress default Cmd+Z or Ctrl+Z behavior and implement a custom input change history. – rishat Commented Dec 21, 2016 at 23:47
  • @RishatMuhametshin, thanks for the link. That's frustrating but thanks anyway :) – Andre Pena Commented Dec 21, 2016 at 23:59
Add a ment  | 

1 Answer 1

Reset to default 5

I didn't solve the problem but it's possibly the best I can do to without re-implementing history as @Rishat mentioned (If I'm mistaken, please let me know).

Thanks to this answer, I got to understand this mand:

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

This basically inserts text in the currently focused input in the current caret position (that's why you don't pass the input as a parameter). And, of course, this function updates the history accordingly.

If I wanted, I could coordinate every insert (like the ** mentioned in the question) in such a way that everything would be in the history. However, that would be too plicated because each markdown mand has a different behavior. It would be too laborious.

Solution:

The following code has to be on ponentDidUpdate, and should only be executed after the text is changed programatically:

// In order to minimize the history problem with inputs, we're doing some tricks:
//  - Set focus on the textarea
//  - Set the value back to its previous value.
//  - Select the whole text (that's the problem)
//  - Insert the new value
this.refs.textarea.focus();
this.refs.textarea.value = previousText;
setSelection(this.refs.textarea, 0, previousText.length);
document.execCommand("insertText", false, text);

Effect

The Ctrl + Z works perfectly, but if you keep going back until the time the input was changed programatically, it will select the whole text. I mean, the history is preserved but at the cost of messing up with the selection if you go back enough. I believe it's good enough, better than re-implementing the input history.

Demo.

发布评论

评论列表(0)

  1. 暂无评论