setSelectionRange не ведет себя одинаково во всех браузерах? - PullRequest
3 голосов
/ 19 января 2012

Я нашел это по другому вопросу:

 setCaretToPos = function(input, selectionStart, selectionEnd){
      if(input.setSelectionRange){
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);

      }else if(input.createTextRange){
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
      }
    };

 setCaretToPos(8, 12);

Он должен выделять текст из текстовой области между 8-м и 12-м символами.

Он работает в Firefox и Chrome, нов опере я получаю неправильный выбор.Смещение сдвигает два символа позади

Что с ним не так?


Кажется, это как-то связано с новыми строками: \n, потому что выбор правильный, если текст несодержит символ новой строки.

1 Ответ

7 голосов
/ 19 января 2012

Новые строки - это два символа (CRLF или \r\n) в текстовых областях в Opera и IE и один символ (\n) в других браузерах. Вы должны будете приспособиться к этому. Вот функция, которая делает это, рассматривая разрывы строк как один символ во всех браузерах.

Живая демоверсия: http://jsfiddle.net/DqtVK/1/

Код:

function adjustOffset(el, offset) {
    var val = el.value, newOffset = offset;
    if (val.indexOf("\r\n") > -1) {
        var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
        newOffset += matches ? matches.length : 0;
    }
    return newOffset;
}

var setCaretToPos = function(input, selectionStart, selectionEnd){
  input.focus();
  if(input.setSelectionRange){
    selectionStart = adjustOffset(input, selectionStart);
    selectionEnd = adjustOffset(input, selectionEnd);
    input.setSelectionRange(selectionStart, selectionEnd);

  }else if(input.createTextRange){
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
};
...