JavaScript: get cursor position in contenteditable div

user2571510 picture user2571510 · Oct 27, 2013 · Viewed 7.9k times · Source

I am pretty new to JavaScript and hope someone here can help me with the following:

Primarily looking for a solution in IE 8 - if it can cover other browsers / versions even better. I have a page with only one contenteditable div that is created dynamically and contains both text and HTML tags. On the page I want to add a button that inserts certain text at the cursor position into this div.

So far I have the following code which works fine as long as I select a text in the div but if I just position my cursor there without selecting anything it inserts my text outside the div.

How can I get it to add my text always at the cursor position the same way it does now at the selection position ? (I don't even need it to replace a selection as it would only be required at the cursor position. Also, this would only be required for one specific div.)

My Code:

<html>
<head>
<script type="text/javascript">
    function test()
    {
        var input = "TEST";
        document.selection.createRange().pasteHTML(input);
    }
</script>

</head>
<body>
    <div id="myDiv" contenteditable>This is a test text.</div><br />
    <button type="button" onclick="test()">Test</button>
</body>
</html>

Thanks for any help with this, Tim

Answer

Tim Down picture Tim Down · Oct 28, 2013

Your problem is that the <button> element steals the focus and destroys the selection by the time the click event has fired in IE. You could make the <button> unselectable, which would prevent it being able to receive focus. This is done using the unselectable attribute in IE:

<button type="button" unselectable="on" onclick="test()">Test</button>

Demo: http://jsbin.com/aqAYUwu/5

Another alternative which is less good in my view is to use the mousedown event instead and prevent the default action:

<button type="button" unselectable="on"
    onmousedown="test(); return false">Test</button>

You can find a cross-browser function to insert HTML at the current cursor position in a contenteditable element here:

https://stackoverflow.com/a/6691294/96100

One final note: contenteditable isn't a boolean attribute so strictly speaking you should give it a value (i.e. <div contenteditable="true">), although <div contenteditable> does work in all browsers I've tried it in.