简体   繁体   中英

Get caret position in textarea (IE)

I want to get the caret position inside text area (Internet Explorer only). I have this:

document.activeElement.focus();             
var sel2 = document.selection.createRange();
sel2.moveStart('character', -document.activeElement.value.length);
var caretPos = sel2.text.length;
alert(caretPos);

If textarea is one line only I get correct result, but if there are many lines the result is wrong because new line takes extra char that is not visible...

How can I get the correct position value (without removing \\r\\n and similar dirty work)?

I would argue that counting line breaks as two characters when calculating selection boundaries/cursor position is the correct approach. Fundamentally, those two characters \\r\\n are there in the text. They are present in the textarea's value property and they are in the value that is submitted to the server.

The only arguments I can see for counting line breaks as one character are:

  1. Consistency with other browsers
  2. IE's TextRange methods consider the line breaks as one character

I think neither is valid. Firstly, IE is already inconsistent with other browsers in counting line breaks as two characters rather than one. Secondly, IE's TextRange character-based methods are a little insane anyway, causing problems wherever they're used.

I think it makes total sense to consider the selection/caret position as a position relative to the actual text in the textarea. This allows easy manipulation of the text.

Here are two main functions. The first is the only textarea selection/caret position getting function I've seen that works correctly with all line breaks. You can find this here: How to get the start and end points of selection in text area? . Second, here's a complementary setSelection function:

function offsetToRangeCharacterMove(el, offset) {
    return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
}

function setSelection(el, startOffset, endOffset) {
    var range = el.createTextRange();
    var startCharMove = offsetToRangeCharacterMove(el, startOffset);
    range.collapse(true);
    if (startOffset == endOffset) {
        range.move("character", startCharMove);
    } else {
        range.moveEnd("character", offsetToRangeCharacterMove(el, endOffset));
        range.moveStart("character", startCharMove);
    }
    range.select();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM