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;
}