JSFiddle - React, Tailwind, and code Playground
HTML
<div id="foo">
Test
<p>Some text in a paragraph</p>
<p>Some more text</p>
<p>More text in a paragraph</p>
More test
</div>
<button id="select">Select</button>
JavaScript
var select = document.getElementById("select");
select.onclick = function() {
var sel = window.getSelection();
if (sel.rangeCount == 0) {
return false;
}
var range = sel.getRangeAt(0);
var object = range.commonAncestorContainer.nodeName === "#text"? range.commonAncestorContainer.parentElement: range.commonAncestorContainer;
var source = object.outerHTML;
var start = getPosition(object, range.startContainer, range.startOffset);
var end = getPosition(object, range.endContainer, range.endOffset);
var data = { object: object, source: source, start: start, end: end};
console.log(data);
return false;
}
function getPosition(node, child, childOffset) {
if (!node.contains(child)) {
return -1;
}
var children = node.childNodes;
var pos = 0;
for (var i = 0; i< children.length; i++) {
if (children[i] === child) {
pos += childOffset;
break;
} else if (children[i].contains(child)) {
pos += getPosition(children[i], child, childOffset);
break;
} else if (children[i].nodeName === "#text") {
pos += children[i].textContent.length;
} else {
pos += children[i].outerHTML.length;
}
}
if (node.nodeName !== "#text") {
pos += node.outerHTML.lastIndexOf(node.innerHTML);
}
return pos;
}