Accounting for `<br>`s in contenteditable caret position : <p>To get and set the caret position in an contenteditable element, I've tried the code from <a href="https://stackoverflow.com/a/3976125/145346">this answer</a>, but the start &amp; end position resets as you move into different text nodes.</p>

<pre><code>&lt;div contenteditable&gt;012345&lt;br&gt;&lt;br&gt;&lt;br&gt;9012345&lt;/div&gt;
</code></pre>

<p>So, I modified the code from <a href="https://stackoverflow.com/a/13950376/145346">this answer</a> (by @TimDown) but it's still <em>not quite</em> counting the line breaks properly... In <a href="http://jsfiddle.net/Mottie/dkc3gvoy/" rel="noreferrer">this demo</a>, when I click after the <code>4</code> and press the right arrow three times, I'll see the start/end report as <code>5</code>, <code>6</code>, then <code>8</code>. Or, use the mouse to select from the <code>4</code> in the first row and continuing selecting to the right (see gif)</p>

<p><a href="https://i.stack.imgur.com/iMzgI.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/iMzgI.gif" alt="selection in contenteditable"></a></p>

<p>Here is the code (<a href="http://jsfiddle.net/Mottie/dkc3gvoy/" rel="noreferrer">demo</a>; even though it looks like it, jQuery is <em>not</em> being used)</p>

<pre><code>function getCaret(el) {
  let start, end;
  const range = document.getSelection().getRangeAt(0),
    preSelectionRange = range.cloneRange(),
    postSelectionRange = range.cloneRange();
  preSelectionRange.selectNodeContents(el);
  preSelectionRange.setEnd(range.startContainer, range.startOffset);
  postSelectionRange.selectNodeContents(el);
  postSelectionRange.setEnd(range.endContainer, range.endOffset);
  start = preSelectionRange.toString().length;
  end = start + range.toString().length;
  // count &lt;br&gt;'s and adjust start &amp; end
  if (start &gt; 0) {
    var node,
      i = el.children.length;
    while (i--) {
      node = el.children[i];
      if (node.nodeType === 1 &amp;&amp; node.nodeName === 'BR') {
        start += preSelectionRange.intersectsNode(el.children[i]) ? 1 : 0;
        end += postSelectionRange.intersectsNode(el.children[i]) ? 1 : 0;
      }
    }
  }
  return {start, end};
}
</code></pre>

<p>The <code>setCaret</code> function modification appears to be working properly (in this basic contenteditable example).</p>

<pre><code>function setCaret(el, start, end) {
  var node, i, nextCharIndex, sel,
    charIndex = 0,
    nodeStack = [el],
    foundStart = false,
    stop = false,
    range = document.createRange();
  range.setStart(el, 0);
  range.collapse(true);
  while (!stop &amp;&amp; (node = nodeStack.pop())) {
    // BR's aren't counted, so we need to increase the index when one
    // is encountered 
    if (node.nodeType === 1 &amp;&amp; node.nodeName === 'BR') {
      charIndex++;
    } else if (node.nodeType === 3) {
      nextCharIndex = charIndex + node.length;
      if (!foundStart &amp;&amp; start &gt;= charIndex &amp;&amp; start &lt;= nextCharIndex) {
        range.setStart(node, start - charIndex);
        foundStart = true;
      }
      if (foundStart &amp;&amp; end &gt;= charIndex &amp;&amp; end &lt;= nextCharIndex) {
        range.setEnd(node, end - charIndex);
        stop = true;
      }
      charIndex = nextCharIndex;
    } else {
      i = node.childNodes.length;
      while (i--) {
        nodeStack.push(node.childNodes[i]);
      }
    }
  }
  sel = document.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
}
</code></pre>

<p>I could use some advice/help with the following issues:</p>

<ul>
<li>How do I properly count the <code>&lt;br&gt;</code>s?</li>
<li><p>How do you count a <code>&lt;br&gt;</code> at the beginning (in this HTML example)?</p>

<pre><code>&lt;div contenteditable&gt;&lt;br&gt;12345&lt;br&gt;&lt;br&gt;&lt;br&gt;9012345&lt;/div&gt;
</code></pre></li>
<li><p>Include <code>&lt;br&gt;</code>'s wrapped in a <code>&lt;div&gt;</code> (in this HTML example) - I'll eventually get to this, but I didn't want to continue down this path and find out there is an easier method.</p>

<pre><code>&lt;div contenteditable&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;12345&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;9012345&lt;/div&gt;
</code></pre></li>
<li><p>I tried to replace the above code with <a href="https://github.com/timdown/rangy/wiki/Rangy-Selection" rel="noreferrer"><code>rangy</code></a>, but it doesn't appear to have a built-in method to get or set a range.</p></li>
</ul>
