Get caret position in HTML input?

How do I get the index of the text caret in an input?


-> selectionStart

<!doctype html>
    
<html>
  <head>
    <meta charset = "utf-8">

    <script type = "text/javascript">
      window.addEventListener ("load", function () {
        var input = document.getElementsByTagName ("input");
        
        input[0].addEventListener ("keydown", function () {
          alert ("Caret position: " + this.selectionStart);
          
          // You can also set the caret: this.selectionStart = 2;
        });
      });
    </script>
    
    <title>Test</title>
  </head>

  <body>
    <input type = "text">
  </body>
</html>

The following will get you the start and end of the selection as character indices. It works for text inputs and textareas, and is slightly complicated because of IE's strange handling of line breaks.

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

var textBox = document.getElementById("textBoxId");
textBox.focus();
alert( getInputSelection(textBox).start ); 

There is now a nice jQuery plugin for this: Caret plugin

Then you can just call $("#myTextBox").caret();


We had used something like this for an old javascript application, but I haven't tested it in a couple years:

function getCaretPos(input) {
    // Internet Explorer Caret Position (TextArea)
    if (document.selection && document.selection.createRange) {
        var range = document.selection.createRange();
        var bookmark = range.getBookmark();
        var caret_pos = bookmark.charCodeAt(2) - 2;
    } else {
        // Firefox Caret Position (TextArea)
        if (input.setSelectionRange)
            var caret_pos = input.selectionStart;
    }

    return caret_pos;
}