Платформа редактора Rich Text Editor для React

Draft.js - это популярный фреймворк для создания любого типа ввода форматированного текста, независимо от того, хотите ли вы поддержать несколько встроенных текстовых стилей или создать сложный текстовый редактор для создания длинных статей. Он используется в Facebook, Medium и многих других популярных веб-приложениях.
Он хорошо адаптирован для различных настольных браузеров, но по-прежнему не поддерживает мобильные браузеры. Есть несколько известных проблем, влияющих на Android и iOS - см. Проблемы с тегами android или IOS для получения информации о текущем состоянии.

Давайте создадим самый простой редактор

Codepen

Как видите, мы создаем специальный объект editorState командой EditorState.createEmpty() и начинаем прослушивать его изменения методомonChange(). Итак, если пользователи пишут, удаляют или перемещают текст с историей отмены / повтора, компонент вернет новый editorState, который будет установлен методом theonChange. Если вы не воспользуетесь этим методом, команды удаления и сохранения не будут работать.

Давайте подробнее рассмотрим, что такое EditorState

EditorState - это неизменяемая запись, которая представляет все состояние редактора черновика и предоставляет доступ к другим полезным неизменяемым объектам редактора:

EditorState состоит из двух объектов:

ContentState

Он обозначает, в какое содержимое HTML-тега будет заключено содержимое. ContentState ничего не знает о позиции курсора. С помощью ContentState вы можете получить информацию о содержимом, модели DOM, тексте и как выглядит статья.

SelectionState

Он предоставляет информацию о , что делает пользователь, где находится курсор, независимо от того, выделяет ли пользователь текст или нет. Только с SelectionState становится возможным найти текущий блок, текущую позицию курсора, текущий выбор, текущую букву. Его методы находятся здесь.

Так, например, если вы хотите знать, какая буква стоит после текущей позиции курсора, вы должны написать это:

Кроме того, с помощью приведенного выше кода вы можете определить, какая буква была написана, и проверить ее.
Например, давайте запретим пользователям вводить более 10 символов:

Codepen

Что такое BlockState и почему мы его используем?

BlockState соответствует элементам блока отображения HTML - всему, что имеет новую строку до и после себя.
Например: <img />, <video />, <div>, <h1>, <h2>.

Выше мы написали функцию, с помощью которой можно получить текущий объект:

const block = getCurrentBlock(editorState)

Если мы попытаемся выяснить, что содержит блок, мы столкнемся с проблемой:

console.log(block)

Мы не видим никакой полезной информации, потому что все объекты редактора обернуты неизменяемыми записями. Эти оболочки не позволяют нам просматривать поля блока с помощью console.log ().
Но на сайте Неизменяемая запись есть метод toObject (), который преобразует неизменяемый объект в обычный объект.

Намного лучше!
Теперь ясно, что блок содержит текст «header h1», заключенный в ‹h1›.

Полезная функция: как удалить блок

Встроенные элементы

Атомарные блоки, такие как «изображение», ничего не содержат, но другие блоки могут содержать встроенные элементы. Встроенные элементы соответствуют InlineRanges в ContentState.. Текст, заключенный в InlineRanges, по умолчанию отображается с ‹span›.
Если встроенный элемент должен включать метаинформацию (например, элемент ‹a› с параметром href), вы должны использовать EntityRange.

Что мне следует использовать, чтобы получить желаемый элемент HTML?

Шаг за шагом, используя все рассмотренные объекты, мы готовимся к созданию редактора форматированного текста с различными блоками.

Codepen

Чтобы увидеть, что именно содержит редактор, в котором вы набираете текст, напишем:

console.log(convertToRaw(editorState.getCurrentContent()))

Затем вы увидите все объекты и параметры, о которых мы ранее говорили:

Давайте сравним этот объект ContentState JSON с HTML (посмотрите на data-offset-key):

Каждый блок стал элементом ‹div›, каждый встроенный диапазон стал ‹span›. Кроме того, каждый элемент имеет свой собственный уникальный ключ, который называется ключом-смещением данных.

ключ-смещение данных

Это уникальный идентификатор каждого тега в редакторе, состоящий из трех разделенных дефисом ключей:

  1. Ключ блока - ключ блока.
  2. Клавиша-декоратор - клавиша необычно стилизованных элементов, например, хэштегов.
  3. Leaf key - ключ встроенного элемента.

Это выглядит как бесполезная системная информация, но в реальной жизни, если вы собираетесь создавать блоки со сложной логикой, это может невероятно вам помочь!

С одной стороны, с помощью «data-offset-keys» вы можете найти любой элемент в DOM. С другой стороны, если вы хотите узнать информацию о тексте внутри определенного элемента HTML, вы можете написать:

Чтобы вручную создать новый элемент HTML, мы должны сгенерировать новый ключ смещения данных. Например, давайте создадим новый блок:

Еще примеры

1. Опросы внутри редактора

Репо здесь

2. Блок кода или более сложный пользовательский блок.

Codepen

3. Предлагайте смайлики

Надеюсь, вы нашли это полезным.
Если вы узнали что-то новое,
нажмите кнопку хлопка 👏 ниже, чтобы это увидело больше людей

Репозитории:

Редактор с блочными и строчными элементами (h1, h2, полужирный, курсив и т. Д.): Https://codepen.io/Katerina198b/pen/GRKawxa

Простой пример с entity: https://codepen.io/Katerina198b/pen/LYPagyO

Уже написана библиотека с расширениями для Draft.js: https://github.com/draft-js-plugins/draft-js-plugins