I have tried to make a text editor and wanted to add a syntax highlighter (I am using a div element).
The code works just fine, but when I type a new character the line thing you type goes at the start of the text. This means that I will type every character at the beginning.
const editor = document.getElementById("text");
var text = editor.innerText;
editor.addEventListener("input", function() {
text = editor.innerText;
editor.innerHTML = text.replaceAll("console", "<font color='green'>console</font>");
console.log(editor.innerHTML);
});
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
<div id="text" contenteditable="true"></div>
Is there any solution I can make that the line does not go at the beginning? Do I have to replace or remove something?
This is because you replace the content on every letter. The solution could indeed be to use the document.createRange() method and the set the caret position manually. You can find alot of duplicates for that question here on SO.
A quick fix would be to use a different event to replace the text on.
For example:
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>
Since we only replace the text once the user stops focussing the div, we avoid the issue of the caret being reset to the start.
Another option would be to use an input element overlayed on top of the div when it gets clicked, instead of using contenteditable. That gives the illusion the user is changing the div, while in reality they are typing inside a real input element, which will give certain advantages, like an onchange event the div lacks by default.
PS: The <font> has been obsolete for years. As the spec states, it'll still work in a lot of browsers, but could be removed any day. You can use a span and CSS as an alternative.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With