JSFiddle - React, Tailwind, and code Playground
HTML
caretXY:<div id="caretXY"></div>
<div id="editor" contenteditable="true">
<p>I had called upon my friend, Mr. Sherlock Holmes, one day in the
autumn of last year and found him in deep conversation with a
very stout, florid–faced, elderly gentleman with fiery red hair.
With an apology for my intrusion, I was about to withdraw when
Holmes pulled me abruptly into the room and closed the door
behind me.</p><p>"You could not possibly have come at a better time, my dear
Watson," he said cordially.</p><p>"I was afraid that you were engaged."</p><p>"So I am. Very much so."</p><p>"Then I can wait in the next room."</p><p>"Not at all. This gentleman, Mr. Wilson, has been my partner and
helper in many of my most successful cases, and I have no
doubt that he will be of the utmost use to me in yours also."</p><p>The stout gentleman half rose from his chair and gave a bob of
greeting, with a quick little questioning glance from his small
fat–encircled eyes.</p><p>"Try the settee," said Holmes, relapsing into his armchair and
putting his fingertips together, as was his custom when in
judicial moods. "I know, my dear Watson, that you share my love
of all that is bizarre and outside the conventions and humdrum
routine of everyday life. You have shown your relish for it by
the enthusiasm which has prompted you to chronicle, and, if you
will excuse my saying so, somewhat to embellish so many of my own
little adventures."</p><p>"Your cases have indeed been of the greatest interest to me," I
observed.</p>
</div>
CSS
#editor {
width: 70%;
overflow: hidden;
position: absolute;
left: 50%;
top: 50%;
margin-left: -160px;
margin-top: -20px;
width: 300px;
min-height: 20px;
line-height: 20px;
padding: 10px;
box-shadow: 0 0 0 1px #ddd;
height: 50%;
}
#caretXY{
position:fixed;
top:25px;
left:5px;
}
JavaScript
$(function () {
$(window).bind('keyup', function(event) {
//$("#caretPos").html(getCaretPos(this));
if (!event.ctrlKey && !event.shiftKey)
getCaretXY();
});
getCaretXY();
});
function getCaretXY(){
// this has got to be a performance drag, but...
// paste a special span at the cursor pos
pasteHtmlAtCaret("<span id='XY'></span>")
// get the XY offset of that element
var XYoffset = $("#XY").offset();
$("#XY").remove();
$("#caretXY").html(XYoffset.top + "," + XYoffset.left);
}
function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}