4

I'm writing a client-side application with Javascript, I'm using the following functions :

function creation() {
var userSelection;
if (window.getSelection) {
    userSelection = window.getSelection();
}
else if (document.selection) { // should come last; Opera!
    userSelection = document.selection.createRange();
}

var rangeObject = getRangeObject(userSelection);
var startOffset = rangeObject.startOffset;
var endOffset = rangeObject.endOffset;
var startCon = rangeObject.startContainer;
var endCon = rangeObject.endContainer;
var myRange = document.createRange();
myRange.setStart(startCon,rangeObject.startOffset);
myRange.setEnd(endCon, rangeObject.endOffset);
$('#result').text(myRange.toString());
}

function getRangeObject(selectionObject) {
if (selectionObject.getRangeAt) {
    var ret = selectionObject.getRangeAt(0);
    return ret;
}
else { // Safari!
    var range = document.createRange();
    range.setStart(selectionObject.anchorNode, selectionObject.anchorOffset);
    range.setEnd(selectionObject.focusNode, selectionObject.focusOffset);
    return range;
     }
}

I need a way to know the character offset related to body element. I found a function with counts the character in an element :

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;
}
Ata Iravani
  • 2,146
  • 7
  • 29
  • 40

1 Answers1

1

That looks like a function from one of my answers. I overcomplicated it a little; see this answer for a simpler function that works in IE < 9 as well: https://stackoverflow.com/a/4812022/96100. You can just pass in document.body as the node parameter. Also, please read the part in the linked answer about the shortcomings of this approach.

Here's a live demo: http://jsfiddle.net/PzQjA/

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • thanks my friend, but I really need is a range with the startOffset and endOffset related to body. This range is selected by client , that's why i used the window.getSelection(). – Ata Iravani Jan 03 '12 at 06:23
  • Note that i use Webkit engine in my project, i does not really need a cross browser solution. – Ata Iravani Jan 03 '12 at 06:24
  • I used your solution but the function u wrote, returns the endOffset, and it ignores line breaks, too – Ata Iravani Jan 03 '12 at 06:28
  • @AtaIravani: As I mentioned in my answer, changing the demo to use the body rather than another element is just a matter of passing `document.body` into `getCaretCharacterOffsetWithin()`. Also, I did mention in the linked answer that the solution is naive and doesn't deal with line breaks created by block elements. Writing a general solution for this is actually surprisingly tricky. I'm currently working on one. – Tim Down Jan 03 '12 at 10:33