JSFiddle - React, Tailwind, and code Playground
by Nico D
HTML
<b>Click with mouse or simply move with arrows inside text:</b>
<div id="test" contenteditable="true">Hello, some <b>bold</b> and <i>italic and <b>bold</b></i> text</div>
<br>
<b>OUTPUT</b><br>
<div id="output"></div>
CSS
span {
background: #0c0;
display: inline-block;
height: 1em;
width: 1em;
}
JavaScript
// Character offset in a Text Box
function getCharacterOffsetWithin(range, node) {
var treeWalker = document.createTreeWalker(
node,
NodeFilter.SHOW_TEXT,
function(node) {
var nodeRange = document.createRange();
nodeRange.selectNodeContents(node);
return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
},
false
);
var charCount = 0;
while (treeWalker.nextNode()) {
charCount += treeWalker.currentNode.length;
}
if (range.startContainer.nodeType == 3) {
charCount += range.startOffset;
}
return charCount;
}
var test = function(e) {
var output;
var el = document.getElementById("test");
var range = window.getSelection().getRangeAt(0);
var positionToUse = document.caretRangeFromPoint(e.clientX, e.clientY);
output = "Caret char pos: " + getCharacterOffsetWithin(range, el) + "<br>Position Pixels: " + e.clientX + " " + e.clientY
+ "<br>Position Pixels 2: " + e.target.offsetLeft + " " + e.target.offsetTop;
document.getElementById("output").innerHTML = output;
//positionToUse.insertNode(document.createElement('span'));
};
window.onclick = test;
// On Typing caretRangeFromPoint has not clientX or clientY
window.onkeyup = test;
//jQuery("#test").keyup(test);