Как установить положение курсора в текстовом поле с помощью 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);

javascript — jQuery.click () против onClick — переполнение стека

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

Живой пример с {{}} (например, Java, C или C #) textarea и input может успешно его выполнить. Если вы хотите, чтобы epmty div использовал его как

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>

. Также вы можете установить другие элементы тем же методом Если вы хотите изменить внутренний HTML после создания, вы можете использовать говорится, что Вы можете использовать

для создания нового

$.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();
        }
    });
};

новый формат отчета JavaScript HTML5

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

Например, цитируя пример, приведенный в (теперь пропавшей) статье

Функция расширения должна выполнить итерацию по каждому выбранному элементу и вернуть 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;
};

внутри (быть ребенком! :).

$.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();

Лучше.

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

мутирует массив и возвращает удаленные индексы. Массив разбивается на части, начиная с индекса, JsonScriptSerializer

. Если вы посмотрите на документацию, вы можете использовать метод RegisterConverters, чтобы добавить пользовательский

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 ), поэтому мне придется отредактировать это в будущем, чтобы убедиться, что часть снова работает. Если у вас есть идея, как это сделать, пожалуйста, прокомментируйте здесь, и я буду рад протестировать это из. Благодарю.

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

var range = elt.createTextRange();
range.move('character', pos);
range.select();

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

$("#comments").focus();
$("#comments").val(comments);

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

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

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

Небольшая модификация кода, который я нашел в 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)

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

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}

На основании этого { *} Вот пара других однострочников функционального стиля, которые я придумал. Они отличаются от решения выше тем, что: Вопрос , ответ не будет работать идеально для 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("rn") > -1) {
        var matches = val.replace(/rn/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);
}

Я должен был заставить это работать для 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

Вы можете напрямую изменить прототип, если 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 link