2016-12-21 1 views
7

Я пытаюсь создать простой React markdown editor.Как включить Ctrl + Z при динамическом изменении текста ввода с помощью React?

editor

Компонент полностью контролируется. Проблема в том, что если пользователь выбирает abc в текстовом поле и нажимает кнопку B, мне нужно позвонить onchange() с **abc**. Мне нужно окружить текст этими звездочками.

Эта разница между тем, что я передаю на onchange(), и то, что пользователь на самом деле набрал, заставляет историю textarea становиться непоследовательными. Ctrl + Z больше не работает.

Demo. [EDIT: В этом демо реализовано исправление. Это не так, как было, когда я задал вопрос]

Как я могу вызвать onchange() в ответ на произвольный текст и сохранить согласованное сочетание Ctrl + Z?

+1

Существует [обсуждение об отмене/повторном стеке] (https://github.com/w3c/editing/issues/150), который дает представление о том, как ваш случай может быть реализован. Идея заключалась бы в подавлении поведения по умолчанию Cmd + Z или Ctrl + Z и реализации пользовательской истории изменений ввода. –

+0

@RishatMuhametshin, спасибо за ссылку. Это расстраивает, но спасибо в любом случае :) –

ответ

1

Я не решил проблему, но это, возможно, самое лучшее, что я могу сделать, без повторной реализации истории, как упоминал @ Ришт (если я ошибаюсь, сообщите мне об этом).

Благодаря this answer, я должен понять эту команду:

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

Это в основном вставляет text в настоящее время сосредоточены вход в текущей позиции курсора (именно поэтому вы не передадите вход в качестве параметра) , И, конечно же, эта функция соответственно обновляет историю.

Если бы я хотел, я мог бы координировать каждую вставку (например, **, упомянутую в вопросе) таким образом, чтобы все было в истории. Однако это было бы слишком сложно, потому что каждая команда уценки имеет другое поведение. Это было бы слишком трудоемко.

Решение:

Следующий код должен быть на componentDidUpdate, и должны быть выполнены только после того, как текст изменен программно:

// 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); 

Эффект

В Ctrl + Z отлично работает, но если вы продолжаете возвращаться до момента ввода s изменяется программно, он выберет весь текст. Я имею в виду, что история сохраняется, но ценой беспорядка с выбором, если вы вернетесь достаточно. Я считаю, что это достаточно хорошо, лучше, чем повторная реализация входной истории.

Demo.

Смежные вопросы