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 ]

294 голосов
/ 08 мая 2009

Вот решение jQuery:

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

С этим вы можете сделать

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position
251 голосов
/ 31 января 2009

У меня есть две функции:

function setSelectionRange(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();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

Тогда вы можете использовать setCaretToPos следующим образом:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

Пример реального времени с textarea и input, показывающий использование из jQuery:

function setSelectionRange(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();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Начиная с 2016 года, протестировано и работает на Chrome, Firefox, IE11, даже IE8 (см. Здесь последние ; фрагменты стека не поддерживают IE8).

37 голосов
/ 06 сентября 2010

Здесь правильные решения, за исключением кода расширения jQuery.

Функция расширения должна перебирать каждый выбранный элемент и возвращать this для поддержки связывания. Вот правильная версия:

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};
22 голосов
/ 24 августа 2011

Я нашел решение, которое работает для меня:

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 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();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

Теперь вы можете переместить фокус в конец любого элемента, вызвав:

$(element).focusEnd();
10 голосов
/ 26 августа 2010

Это сработало для меня в Safari 5 на Mac OSX, jQuery 1.4:

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;
7 голосов
/ 03 декабря 2015

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

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

Использование ctrl-enter для добавления новой строки (как в Facebook):

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

Я открыт для критики. Спасибо.

ОБНОВЛЕНИЕ: Это решение не позволяет работать нормальной функции копирования и вставки (т. Е. Ctrl-c, ctrl-v), поэтому мне придется отредактировать это в будущем, чтобы убедиться, что часть работает снова. Если у вас есть идея, как это сделать, пожалуйста, прокомментируйте здесь, и я буду рад проверить это. Спасибо.

7 голосов
/ 18 января 2010

Я использую это: http://plugins.jquery.com/project/jCaret

6 голосов
/ 01 января 2013

Установите фокус, прежде чем вставить текст в текстовое поле таким образом?

$("#comments").focus();
$("#comments").val(comments);
6 голосов
/ 14 мая 2009

В IE для перемещения курсора на какую-то позицию этого кода достаточно:

var range = elt.createTextRange();
range.move('character', pos);
range.select();
5 голосов
/ 28 июня 2015

Это работает для меня в Chrome

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

Очевидно, вам нужна задержка в микросекунду или больше, потому что обычно пользователь фокусируется на текстовом поле, щелкая мышью в какой-то позиции в текстовом поле (или нажимая на вкладку), которую вы хотите переопределить, поэтому вам придется подождать положение задается щелчком пользователя, а затем изменяется.

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