Testing Caret Position - Resolved

Comparing the reported caret position in IE versus a Gecko-based browser.

by FishBasketGordo

HTML

<textarea id="txt" rows="20" cols="30"></textarea><br/>
<span id="txtStats"></span><br/>

JavaScript

function getCaretPosGecko(txtbox) {
    return txtbox.selectionStart;
}

function getCaretPosIE(txtbox) {
    var caret, normalizedValue, range, textInputRange, len, endRange;

    txtbox.focus();
    range = document.selection.createRange();

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

        // Create a working TextRange that lives only in the input
        textInputRange = txtbox.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 = txtbox.createTextRange();
        endRange.collapse(false);

        if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
            caret = txtbox.value.replace(/\r\n/g, '\n').length;
        } else {
            caret = -textInputRange.moveStart("character", -len);
            caret += normalizedValue.slice(0, start).split("\n").length - 1;
        }
    }
}

function getCaretPos(txtbox) {
    if (txtbox.selectionStart != undefined) {
        return getCaretPosGecko(txtbox);
    } else if (document.selection) {
        return getCaretPosIE(txtbox);
    }
}

$('#txt').keyup(function(event) {
    var text = $(this).val(),
        caret = getCaretPos(this);

    $('#txtStats').text('length = ' + text.length + ', caret = ' + caret);
});