Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
112
rated 0 times [  117] [ 5]  / answers: 1 / hits: 78167  / 14 Years ago, sat, january 22, 2011, 12:00:00

I have contentEditable element (can be p, div, ...) and I would like to get caret (cursor) position in it. I can normally achieve it with this piece of code:



var position = window.getSelection().getRangeAt(0).startOffset;


This works fine while the element contains just text. But when the element contains some HTML formatting, the returned position is relative to caret position within included HTML element.



Let's assume contents of contentEditable element is this:



AB<b>CD</b>EF


If caret is inside <b></b>, let's say between C and D, the returned position with above code is 1 instead of 3 (counted from the begining of the contentEditable element's content)



Can anybody come up with solution to this ?


More From » wysiwyg

 Answers
60

UPDATE



I've written a simpler version of this that also works in IE < 9:



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



Old Answer



This is actually a more useful result than a character offset within the text of the whole document: the startOffset property of a DOM Range (which is what window.getSelection().getRangeAt() returns) is an offset relative to its startContainer property (which isn't necessarily always a text node, by the way). However, if you really want a character offset, here's a function that will do it.



Here's a live example: http://jsfiddle.net/timdown/2YcaX/



Here's the function:



function getCharacterOffsetWithin(range, node) {
var treeWalker = document.createTreeWalker(
node,
NodeFilter.SHOW_TEXT,
function(node) {
var nodeRange = document.createRange();
nodeRange.selectNode(node);
return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
},
false
);

var charCount = 0;
while (treeWalker.nextNode()) {
charCount += treeWalker.currentNode.length;
}
if (range.startContainer.nodeType == 3) {
charCount += range.startOffset;
}
return charCount;
}

[#94100] Thursday, January 20, 2011, 14 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
karladaijahf

Total Points: 78
Total Questions: 123
Total Answers: 89

Location: Liechtenstein
Member since Wed, Dec 8, 2021
2 Years ago
;