jQuery Установить положение курсора в текстовой области - PullRequest
429 голосов
/ 31 января 2009

Как установить позицию курсора в текстовом поле с помощью jQuery? У меня есть текстовое поле с содержимым, и я хочу, чтобы курсор пользователя располагался с определенным смещением, когда он фокусируется на поле. Код должен выглядеть примерно так:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

Как будет выглядеть реализация этой функции setCursorPosition? Если у вас есть текстовое поле с содержимым abcdefg, этот вызов приведет к позиционированию курсора следующим образом: abcd ** | ** efg.

Java имеет аналогичную функцию setCaretPosition. Существует ли подобный метод для javascript?

Обновление: я изменил код CMS для работы с jQuery следующим образом:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

Ответы [ 15 ]

4 голосов
/ 11 апреля 2012

Небольшая модификация кода, который я нашел в bitbucket

Код теперь может выбирать / выделять начальную / конечную точки, если дано 2 позиции. Протестировано и отлично работает в FF / Chrome / IE9 / Opera.

$('#field').caret(1, 9);

Код указан ниже, изменилось только несколько строк:

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)
3 голосов
/ 02 февраля 2012

Исходя из этого вопроса , ответ не будет работать идеально для ie и opera, когда в текстовой области появится новая строка. ответ объясняет, как настроить selectionStart, selectionEnd перед вызовом setSelectionRange.

Я попробовал настроить AdjustOffset из другого вопроса с решением, предложенным @AVProgrammer, и он работает.

function adjustOffset(el, offset) {
    /* From https://stackoverflow.com/a/8928945/611741 */
    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;
}

$.fn.setCursorPosition = function(position){
    /* From https://stackoverflow.com/a/7180862/611741 */
    if(this.lengh == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    /* From https://stackoverflow.com/a/7180862/611741 
       modified to fit https://stackoverflow.com/a/8928945/611741 */
    if(this.lengh == 0) return this;
    input = this[0];

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

    return this;
}

$.fn.focusEnd = function(){
    /* From https://stackoverflow.com/a/7180862/611741 */
    this.setCursorPosition(this.val().length);
}
3 голосов
/ 08 марта 2011

Просто не забывайте возвращать false сразу после вызова функции, если вы используете клавиши со стрелками, так как в противном случае Chrome обманывает фрак.

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}
2 голосов
/ 03 апреля 2017

Я должен был заставить это работать для contenteditable элементов и jQuery и подумал, что кто-то может захотеть, чтобы он был готов к использованию:

$.fn.getCaret = function(n) {
    var d = $(this)[0];
    var s, r;
    r = document.createRange();
    r.selectNodeContents(d);
    s = window.getSelection();
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return s.anchorOffset;
};

$.fn.setCaret = function(n) {
    var d = $(this)[0];
    d.focus();
    var r = document.createRange();
    var s = window.getSelection();
    r.setStart(d.childNodes[0], n);
    r.collapse(true);
    s.removeAllRanges();
    s.addRange(r);
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return this;
};

Использование $(selector).getCaret() возвращает смещение числа, а $(selector).setCaret(num) устанавливает отклонение и устанавливает фокус на элемент.

Также небольшой совет: если вы запустите $(selector).setCaret(num) из консоли, он вернет console.log, но вы не будете визуализировать фокус, поскольку он установлен в окне консоли.

Bests; D

1 голос
/ 17 октября 2011

Вы можете напрямую изменить прототип, если setSelectionRange не существует.

(function() {
    if (!HTMLInputElement.prototype.setSelectionRange) {
        HTMLInputElement.prototype.setSelectionRange = function(start, end) {
            if (this.createTextRange) {
                var range = this.createTextRange();
                this.collapse(true);
                this.moveEnd('character', end);
                this.moveStart('character', start);
                this.select();
            }
        }
    }
})();
document.getElementById("input_tag").setSelectionRange(6, 7);

jsFiddle ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...