Исправляем contenteditable в Chrome: с <div> на <br>

Пройдите тест, узнайте какой профессии подходите
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам требуется предотвратить автоматическую вставку тегов <div> при нажатии на клавишу Enter внутри элемента contenteditable, примените следующий код на JavaScript:

JS
Скопировать код
document.addEventListener('keydown', function(e) {
  if (e.key === 'Enter' && !e.shiftKey) { // Обрабатываем нажатие клавиши Enter без Shift, чтобы не ломать создание нового абзаца
    document.execCommand('insertLineBreak'); // Заменяет div на br
    e.preventDefault(); // Нежелательные div больше не образуются
  }
});

Таким образом, вы предотвратите автоматическое создание тегов <div> при нажатии на Enter, заменив их на операцию insertLineBreak. Вот так вот программирование работает!

Пошаговый план для смены профессии

Улучшаем пользовательский опыт

Чтобы поведение contenteditable было прогнозируемо для пользователя, необходимо переопределить реакцию на клавишу Enter. По умолчанию этот ответ разный в разных браузерах, но мы можем оказать на это влияние. Вот как это сделать:

Вставляем <br>, а не блоковые элементы

Отключаем автоматическое создание блоков при формировании новой строки:

JS
Скопировать код
document.execCommand('insertHTML', false, '<br><br>');

Вместо использования insertLineBreak мы применяем insertHTML, вставляя два тега <br> и тем самым имитируя двойной перевод строки без лишнего блочного элемента.

Блокируем стандартное поведение

Препятствуем созданию ненужных элементов:

JS
Скопировать код
if (e.key === 'Enter') {
  e.preventDefault(); // Так div-элементы нам больше не помешают!
}

Вызов event.preventDefault() заставляет клавишу Enter подчиниться новым правилам и не создавать ненужных элементов.

Визуализация

Демонстрация процесса вставки <div> в contenteditable при нажатии на ENTER в браузере Chrome и способа его предотвращения:

Markdown
Скопировать код
До:
[✍️] -> [🔨 добавление <div>]

После:
[✍️] -> [🛑] -> [✏️ Продолжение без <div>]

Особенность: Мы установили стоп-сигнал 🛑, который блокирует автоматическое создание тега <div> в Chrome и заменяет его на операцию нажатия Enter.

JS
Скопировать код
document.execCommand('defaultParagraphSeparator', false, 'p');
// Меняем автоматическую вставку тега <div> на <p> в Chrome при нажатии клавиши Enter

Применение стилей CSS

Можно изменить поведение contenteditable, воспользовавшись несколькими способами оформления CSS:

Использование Inline-block

Для предотвращения автоматического создания тегов применим стиль:

CSS
Скопировать код
[contenteditable] {
  display: inline-block; /* Использование inline-block помогает нам в борьбе с автоматическими div */
}

Работа с пробелами и переносами

Используем CSS для корректного отображения пробелов и переводов строк:

CSS
Скопировать код
[contenteditable] {
  white-space: pre-wrap; /* Учитывает и переводы строк, и пробелы */
}

Управление курсором и устранение лишних <br>

Для контроля над положением курсора используем window.getSelection(). Для работы с тегами <br> обращаемся к JavaScript, чтобы поддерживать чистоту кода.

Проверка совместимости и особые случаи

Хоть и Chrome зачастую является предметом нашего внимания, не стоит забывать и о других браузерах. Ниже приведены несколько дополнительных примеров работы с DOM и CSS:

Совместимость с различными браузерами

Обязательно проверьте работу решения во всех ведущих браузерах, включая Firefox, Safari и Edge. Интерпретация contenteditable может отличаться в разных браузерах.

Работа с DocumentFragment и Range

Продвинутые методы управления DOM, такие как document.createDocumentFragment() и range.deleteContents(), в сочетании с range.insertNode(), обеспечивают точное позиционирование нового контента.

Настройка поведения контейнеров

С помощью свойств CSS, таких как background, margin и padding, можно настроить взаимодействие элемента contenteditable с окружающими элементами.

Полезные материалы

  1. contenteditable – HTML: HyperText Markup Language | MDN – Всё, что вы хотели знать о contenteditable.
  2. Dealing with Line Breaks on contentEditable DIV – Stack Overflow – Обсуждение удаления нежелательных тегов <div> на Stack Overflow.
  3. HTML Global contenteditable Attribute – Краткий обзор и примеры использования contenteditable.
  4. The contenteditable attribute | HTML5 Doctor – Глубокий анализ contenteditable.
  5. Medium – Анализ преимуществ и недостатков contenteditable.
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какое действие выполняет код для предотвращения вставки тегов <div> при нажатии на Enter?
1 / 5