====== JavaScript - Position - Get caret position in contentEditable ====== The Range instance returned by various Selection methods – most commonly window.getSelection().getRangeAt(0) – does not provide enough information to determine the total offset of the caret (or selection start/end). Here’s how: var SelectionUtils = {}; /** * Returns an object with 2 properties: a boolean value indicating if #child was found in the currently iterating * set of child nodes, and an integer value representing how many characters of textContent were examined in that same * iteration. * @private * @param {Node} child * @param {Node} container * @returns {{offset: number, found: boolean}} */ SelectionUtils.getCharacterCountToNodeRecursive = function(child, container){ var response = { offset : 0, found : false }; var current = container.firstChild; loop: while(current){ if(current == child){ response.found = true; break; } switch(current.nodeType){ case 3 : response.offset += current.textContent.length; break; case 1 : var childResponse = arguments.callee(child, current); response.offset += childResponse.offset; if(childResponse.found){ response.found = true; break loop; } break; } current = current.nextSibling; } return response; }; /** * Returns the number of characters of text content preceding #child, in #container. * @param {Node} child * @param {Node} container * @returns {number} */ SelectionUtils.getCharacterCountToNode = function(child, container){ container = container || document.body; if(!container.contains(child)){ throw new Error('child must be descendant of container'); } return SelectionUtils.getCharacterCountToNodeRecursive(child, container).offset; }; /** * Convenience method to count the number of characters of text content to the start of the current selection. * @param range * @param container * @returns {number} */ SelectionUtils.getSelectionStartOffset = function(range, container){ return range.startOffset + SelectionUtils.getCharacterCountToNode(range.startContainer, container); }; /** * Convenience method to count the number of characters of text content to the end of the current selection. * @param range * @param container * @returns {number} */ SelectionUtils.getSelectionEndOffset = function(range, container){ return range.endOffset + SelectionUtils.getCharacterCountToNode(range.endContainer, container); };

This is a paragraph.

This is also a paragraph.

---- {{:javascript:position:css_-_content_editable.png?800|}}