Это потому, что вы заменяете содержимое каждой буквы.Решением может быть использование метода document.createRange()
и установка позиции каретки вручную.Вы можете найти множество дубликатов для этого вопроса здесь, на SO.
Быстрое решение проблемы - использовать другое событие для замены текста на.
Например:
const editor = document.getElementById("text");
var text = editor.innerText;
editor.addEventListener("focusout", function() {
text = editor.innerText;
editor.innerHTML = text.replaceAll("console", '<span class="highlighted">console</span>');
console.log(editor.innerHTML);
});
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
.highlighted {
color: green;
}
<div id="text" contenteditable="true">Test string</div>
Поскольку мы заменяем текст только после того, как пользователь перестает фокусировать элемент div, мы избегаем проблемы возврата каретки в начало.
Другой вариант - использовать элемент ввода, наложенный поверх элемента div при нажатии на него, вместо использования contenteditable
.Это дает иллюзию, что пользователь изменяет div, в то время как на самом деле он печатает внутри реального элемента ввода, что дает определенные преимущества, например, при событии onchange, которого div по умолчанию не хватает.
PS: <font>
устарел в течение многих лет.Как говорится в спецификации, он по-прежнему будет работать во многих браузерах, но может быть удален в любой день.Вы можете использовать span и CSS в качестве альтернативы.