Исправляем contenteditable в Chrome: с <div> на <br>
Быстрый ответ
Если вам требуется предотвратить автоматическую вставку тегов <div>
при нажатии на клавишу Enter внутри элемента contenteditable
, примените следующий код на JavaScript:
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>
, а не блоковые элементы
Отключаем автоматическое создание блоков при формировании новой строки:
document.execCommand('insertHTML', false, '<br><br>');
Вместо использования insertLineBreak
мы применяем insertHTML
, вставляя два тега <br>
и тем самым имитируя двойной перевод строки без лишнего блочного элемента.
Блокируем стандартное поведение
Препятствуем созданию ненужных элементов:
if (e.key === 'Enter') {
e.preventDefault(); // Так div-элементы нам больше не помешают!
}
Вызов event.preventDefault()
заставляет клавишу Enter подчиниться новым правилам и не создавать ненужных элементов.
Визуализация
Демонстрация процесса вставки <div>
в contenteditable
при нажатии на ENTER в браузере Chrome и способа его предотвращения:
До:
[✍️] -> [🔨 добавление <div>]
После:
[✍️] -> [🛑] -> [✏️ Продолжение без <div>]
Особенность: Мы установили стоп-сигнал 🛑, который блокирует автоматическое создание тега <div>
в Chrome и заменяет его на операцию нажатия Enter
.
document.execCommand('defaultParagraphSeparator', false, 'p');
// Меняем автоматическую вставку тега <div> на <p> в Chrome при нажатии клавиши Enter
Применение стилей CSS
Можно изменить поведение contenteditable
, воспользовавшись несколькими способами оформления CSS:
Использование Inline-block
Для предотвращения автоматического создания тегов применим стиль:
[contenteditable] {
display: inline-block; /* Использование inline-block помогает нам в борьбе с автоматическими div */
}
Работа с пробелами и переносами
Используем 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
с окружающими элементами.
Полезные материалы
- contenteditable – HTML: HyperText Markup Language | MDN – Всё, что вы хотели знать о
contenteditable
. - Dealing with Line Breaks on contentEditable DIV – Stack Overflow – Обсуждение удаления нежелательных тегов
<div>
на Stack Overflow. - HTML Global contenteditable Attribute – Краткий обзор и примеры использования
contenteditable
. - The contenteditable attribute | HTML5 Doctor – Глубокий анализ
contenteditable
. - Medium – Анализ преимуществ и недостатков
contenteditable
.