7

I'd like to set caret position in a content editable element but it seem's not working.

var el = document.getElementsByTagName('div')[0];
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el, 2);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
el.focus();
<div contenteditable>Hi ! How are you doing ?</div>
tonymx227
  • 5,293
  • 16
  • 48
  • 91

2 Answers2

20

Try this:
Just replace range.setStart(el, 2) with range.setStart(el.childNodes[0], 2)

var el = document.getElementsByTagName('div')[0];
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el.childNodes[0], 2);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
el.focus();
<div contenteditable>Hi ! How are you doing ?</div>

You are passing the wrong node to the setStart function. Need to pass a text node.

Rakesh G R
  • 804
  • 12
  • 24
  • @tonymx227 have a look at user2693928's answer for details http://stackoverflow.com/questions/40632975/set-caret-position-in-a-content-editable-element/40633278#40633278 – Rakesh G R Nov 16 '16 at 13:32
  • Is there any downside to removing all ranges and adding a new range to the selection? – Alexandra Oct 02 '18 at 15:08
  • 1
    @Alexandra selection anywhere else in the window will be lost; apart from that...nope. – Rakesh G R Oct 02 '18 at 20:04
1

If the startNode is a Node of type Text, Comment, or CDATASection, then startOffset is the number of characters from the start of startNode. For other Node types, startOffset is the number of child nodes between the start of the startNode.

If it's not textarea it counds the child elements for offsets.

You can set different elements in the contenteditable like this:

<div contenteditable>
<p>para 1</p>
<p>para 2</p>
<p>para 3</p>
<p>para 4</p>
</div>
<script>
    var el = document.getElementsByTagName('div')[0];
    var p = document.querySelector('p');
    var range = document.createRange();
    var sel = window.getSelection();
    range.setStart(el, 3);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    el.focus();
</script>