views:

284

answers:

2

i want to get the cursor start and end position of a selected range in a text-field or text-area. i tried lot of functions in various forums. but when the last character of the selection is a new line character JavaScript ignore it in IE6. any one having idea ?

+6  A: 

Revised answer, 5 September 2010

To account for trailing line breaks is tricky in IE, and I haven't seen any solution that does this. It is possible, however. The following is an new version of what I previously posted here.

function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}
Tim Down
thank you very much Tim Down,i already tried this thread. but the problem is when the last character of the selection is a new line character JavaScript ignore it in IE. otherwise those functions working fine
Nayana Adassuriya
Answer now completely rewritten.
Tim Down
Ah: it breaks if there is a non-caret selection. Fixing...
Tim Down
thank you very much Tim Down,this method working fine. for simple cursor position. but if we select a text range for get the start position of the selected text. that selected text automatically deleting. so how can i correct this. any way this is a nice trick and u make a gr8 invention.
Nayana Adassuriya
Yes, that's the same problem that I spotted. I've fixed it now.
Tim Down
Ohooo gr8 it is working fine!!!thank you very much Tim Down,and another help for me!!. i want to fine the end point of the selection as well in same function.How can i implement that requirment.
Nayana Adassuriya
I've added a parameter to specify start or end position.
Tim Down
Thank you very much Tim Down. totally solved the problem
Nayana Adassuriya
Answer improved again after a little more work.
Tim Down
A: 

I needed to do something very similar and came up with this:

function getSelection(target) {
    var s = {start: 0, end:0};
    if (typeof target.selectionStart == "number"
        && typeof target.selectionEnd == "number") {
        // Firefox (and others)
        s.start = target.selectionStart;
        s.end = target.selectionEnd;
    } else if (document.selection) {
        // IE
        var bookmark = document.selection.createRange().getBookmark();
        var sel = target.createTextRange();
        var bfr = sel.duplicate();
        sel.moveToBookmark(bookmark);
        bfr.setEndPoint("EndToStart", sel);
        s.start = bfr.text.length;
        s.end = s.start + sel.text.length;
    }
    return s;
}

Notes:

  • The sel range must be created by target rather than using the range returned by document.selection, otherwise bfr.setEndPoint will complain about an invalid argument. This "feature" (discovered in IE8) does not appear to be documented in the spec.
  • target must have input focus for this function to work.
  • Only tested with <textarea>, might work with <input> as well.
Daniel