JSFiddle - React, Tailwind, and code Playground
by minitech
HTML
<div id="editor" contenteditable="true">1234<span>56789</span>10</div>
<span id="position"></span>
JavaScript
function getContentLength(element) {
var stack = [element];
var total = 0;
var current;
while(current = stack.pop()) {
for(var i = 0; i < current.childNodes.length; i++) {
if(current.childNodes[i].nodeType === 1) {
stack.push(current.childNodes[i]);
} else if(current.childNodes[i].nodeType === 3) {
total += current.childNodes[i].nodeValue.length;
}
}
}
return total;
}
function getSelectionOffsetFrom(parent) {
var sel = window.getSelection();
var current = sel.anchorNode;
var offset = sel.anchorOffset;
while(current && current !== parent) {
var sibling = current;
while(sibling = sibling.previousSibling) {
if(sibling.nodeType === 3) {
offset += sibling.nodeValue.length;
} else if(sibling.nodeType === 1) {
offset += getContentLength(sibling);
}
}
current = current.parentNode;
}
if(!current) {
return null;
}
return offset;
}
document.addEventListener('DOMContentLoaded', function() {
var position = document.getElementById('position');
var editor = document.getElementById('editor');
setInterval(function() {
position.textContent = 'Selection starts at ' + getSelectionOffsetFrom(editor);
}, 100);
});