JSFiddle - React, Tailwind, and code Playground
HTML
<div id="editable" contenteditable="true">Typing a brace here works --
<br> but not here --
<br>footer
<br>
</div>
CSS
#editable {
width: 300px;
height:300px;
}
JavaScript
document.getElementById("editable").onkeyup = handleKeyUp;
document.getElementById("editable").focus();
function getSelectionStart(element) {
if (element.tagName === "DIV") {
var caretOffset = 0,
doc = element.ownerDocument || element.document,
win = doc.defaultView || doc.parentWindow;
element.focus();
var range = win.getSelection().getRangeAt(0),
preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
return caretOffset;
} else {
return element.selectionStart;
}
}
function getTextNodesIn(node) { // helper
var textNodes = [];
if (node.nodeType == 3) {
textNodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; ++i) {
textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
}
}
return textNodes;
}
function highlightText(el, start, end) { // main
if (el.tagName === "DIV") { // content-editable div
var range = document.createRange();
range.selectNodeContents(el);
var textNodes = getTextNodesIn(el);
var foundStart = false;
var charCount = 0,
endCharCount;
for (var i = 0, textNode; textNode = textNodes[i++];) {
endCharCount = charCount + textNode.length;
if (!foundStart && start >= charCount && (start < endCharCount || (start == endCharCount && i < textNodes.length))) {
range.setStart(textNode, start - charCount);
foundStart = true;
}
if (foundStart && end <= endCharCount) {
range.setEnd(textNode, end - charCount);
break;
}
charCount = endCharCount;
}
var sel = window.getSelection();
...