Установить позицию курсора клавиатуры в текстовом поле html

Кто-нибудь знает, как переместить курсор клавиатуры в текстовом поле в определенную позицию?

Например, если текстовое поле (например, элемент ввода, а не текстовая область) содержит 50 символов, и я хочу разместить курсор перед символом 20, как мне это сделать?

В этом отличие от этого вопроса: jQuery Установить положение курсора в текстовой области, для чего требуется jQuery.


person jonhobbs    schedule 04.02.2009    source источник


Ответы (9)


Взято из Установка позиции курсора клавиатуры в текстовом поле или TextArea с помощью Javascript

Общая функция, которая позволит вам вставить курсор в любую позицию текстового поля или текстового поля, которое вы хотите:

function setCaretPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

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

Протестировано в IE6 и выше, Firefox 2, Opera 8, Netscape 9, SeaMonkey и Safari. К сожалению, в Safari это не работает в сочетании с событием onfocus).

Пример использования вышеуказанной функции для принудительного перехода курсора клавиатуры к концу всех текстовых полей на странице, когда они получают фокус:

function addLoadEvent(func) {
    if(typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        if(func) {
            var oldLoad = window.onload;

            window.onload = function() {
                if(oldLoad)
                        oldLoad();

                func();
            }
        }
    }
}

// The setCaretPosition function belongs right here!

function setTextAreasOnFocus() {
/***
 * This function will force the keyboard caret to be positioned
 * at the end of all textareas when they receive focus.
 */
    var textAreas = document.getElementsByTagName('textarea');

    for(var i = 0; i < textAreas.length; i++) {
        textAreas[i].onfocus = function() {
            setCaretPosition(this.id, this.value.length);
        }
    }

    textAreas = null;
}

addLoadEvent(setTextAreasOnFocus);
person Ta01    schedule 04.02.2009
comment
if(elem.selectionStart) прерывается, когда selectionStart равно 0, что также указано в ответе jhnns. - person mpartel; 01.09.2012
comment
У меня это не работает. Когда я щелкаю фактическое текстовое поле, я ожидаю, что позиция курсора будет в начале. Проверьте мою скрипку jsfiddle.net/khx2w - person elad.chen; 19.07.2013
comment
Функция setCaretPosition работает нормально. Однако ваша функция addActionHandler этого не делает. Но даже без этого я не мог заставить курсор перемещаться в фокусе. Скорее всего, это потому, что браузер сам устанавливает положение курсора в зависимости от положения щелчка. Из того, что я могу сказать, кажется, нет никакого способа обойти это, но я могу полностью ошибаться. - person GJK; 19.07.2013
comment
Работает в IE9, FF25, но не в Chrome 30. Лучше, чем ничего! - person Umber Ferrule; 14.11.2013
comment
У меня elem.value = elem.value.replace(/^9/g,'+79') в коде. На курсоре OperaMINI после +. эта функция не помогает - person eri; 26.12.2016
comment
Ссылка на блог мертва. - person Cloud; 31.01.2020
comment
@Cloud, поэтому отрывок приведен выше. - person Ta01; 31.01.2020
comment
Упс, я неправильно понял отрывок. Слишком привык видеть маленькие цитаты желтым. Понятно, спасибо за мгновенный ответ. - person Cloud; 31.01.2020
comment
Просто укажите здесь, что здесь используется специфичная для MS функция. Я все еще ищу другие решения. - person Cloud; 31.01.2020
comment
Обратите внимание, что по состоянию на 2020 год этот ответ стал немного вводить в заблуждение, потому что он содержит много кода для работы с браузерами, которые не поддерживают setSelectionRange: это имело смысл в 2009 году, но не имело места с 2016 года, когда последний браузер который его не поддерживал - IE8 - был окончательно уничтожен. С тех пор в резервном коде необходимости не было. Также обратите внимание, что вся процедура загрузки теперь покрывается атрибутом defer в элементе <script> (запускает скрипт только после того, как документ полностью проанализирован), который пользуется универсальной поддержкой с IE10 (который с тех пор перешел на EOL). - person Mike 'Pomax' Kamermans; 16.10.2020

Ссылка в ответе не работает, она должна работать (все кредиты идут на blog.vishalon.net):

http://snipplr.com/view/5144/getset-cursor-in-html-textarea/.

Если код снова потеряется, вот две основные функции:

function doGetCaretPosition(ctrl)
{
 var CaretPos = 0;

 if (ctrl.selectionStart || ctrl.selectionStart == 0)
 {// Standard.
  CaretPos = ctrl.selectionStart;
 }
 else if (document.selection)
 {// Legacy IE
  ctrl.focus ();
  var Sel = document.selection.createRange ();
  Sel.moveStart ('character', -ctrl.value.length);
  CaretPos = Sel.text.length;
 }

 return (CaretPos);
}


function setCaretPosition(ctrl,pos)
{
 if (ctrl.setSelectionRange)
 {
  ctrl.focus();
  ctrl.setSelectionRange(pos,pos);
 }
 else if (ctrl.createTextRange)
 {
  var range = ctrl.createTextRange();
  range.collapse(true);
  range.moveEnd('character', pos);
  range.moveStart('character', pos);
  range.select();
 }
}
person eternal    schedule 29.11.2010
comment
+1 для базовых функций, хотя необходимо внести некоторые изменения. При использовании метода диапазона количество строк должно быть вычтено из pos. - person Rob W; 05.06.2012

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

Наслаждайтесь! Работает в IE6 +, Firefox, Chrome, Safari, Opera

Метод кроссбраузерного позиционирования курсора (пример: перемещение курсора в конец)

// ** USEAGE ** (returns a boolean true/false if it worked or not)
// Parameters ( Id_of_element, caretPosition_you_want)

setCaretPosition('IDHERE', 10); // example

Мясо и картофель - это, в основном, setCaretPosition @ kd7, с самой большой настройкой if (el.selectionStart || el.selectionStart === 0), в firefox selectionStart начинается с 0, что в логическом выражении, конечно, превращается в Ложь, значит, он ломался там.

В Chrome самая большая проблема заключалась в том, что просто дать ему .focus() было недостаточно (он продолжал выделять ВСЕ текст!) Следовательно, мы устанавливаем само значение el.value = el.value; перед вызовом нашей функции, и теперь у него есть захват и положение с вводом для использования selectionStart.

function setCaretPosition(elemId, caretPos) {
    var el = document.getElementById(elemId);

    el.value = el.value;
    // ^ this is used to not only get "focus", but
    // to make sure we don't have it everything -selected-
    // (it causes an issue in chrome, and having it doesn't hurt any other browser)

    if (el !== null) {

        if (el.createTextRange) {
            var range = el.createTextRange();
            range.move('character', caretPos);
            range.select();
            return true;
        }

        else {
            // (el.selectionStart === 0 added for Firefox bug)
            if (el.selectionStart || el.selectionStart === 0) {
                el.focus();
                el.setSelectionRange(caretPos, caretPos);
                return true;
            }

            else  { // fail city, fortunately this never happens (as far as I've tested) :)
                el.focus();
                return false;
            }
        }
    }
}
person Mark Pieszak - Trilon.io    schedule 20.09.2012
comment
@mcpDESIGNS Я пытаюсь использовать эту функцию, когда фокус сделан на ввод текста, но я никуда не ухожу. Не могли бы вы помочь с применением этой функции, используя чистый javascript? - person elad.chen; 19.07.2013
comment
@ elad.chen Вы пытаетесь поместить их в конец текстового поля, как только они сфокусируются на нем? - person Mark Pieszak - Trilon.io; 19.07.2013
comment
@mcpDESIGNS Я хочу поместить курсор в начало поля, как только элемент будет сфокусирован. См. Скрипку: jsfiddle.net/KuLTU/3 - person elad.chen; 19.07.2013
comment
@ elad.chen Извините за безумно поздний ответ! Просто измените это событие на .onclick вместо .onfocus в вашей функции search_field_focus. - person Mark Pieszak - Trilon.io; 23.01.2015
comment
el.value = el.value; [...] if(el !== null) - Я бы поменял эти две строчки местами. Если el имеет значение null, el.value = el.value завершится ошибкой, поэтому эта строка должна находиться внутри if. - person BackSlash; 07.05.2018

Я немного скорректировал ответ kd7, потому что elem.selectionStart будет оценивать как false, когда selectionStart случайно равен 0.

function setCaretPosition(elem, caretPos) {
    var range;

    if (elem.createTextRange) {
        range = elem.createTextRange();
        range.move('character', caretPos);
        range.select();
    } else {
        elem.focus();
        if (elem.selectionStart !== undefined) {
            elem.setSelectionRange(caretPos, caretPos);
        }
    }
}
person Johannes Ewald    schedule 19.04.2012

Я нашел простой способ решить эту проблему, протестированный в IE и Chrome:

function setCaret(elemId, caret)
 {
   var elem = document.getElementById(elemId);
   elem.setSelectionRange(caret, caret);
 }

Передайте этой функции идентификатор текстового поля и позицию курсора.

person Iam_NSA    schedule 29.08.2019

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

$("#myinputfield").focus().val($("#myinputfield").val());
person manish_s    schedule 14.01.2014

Я бы исправил такие условия, как показано ниже:

function setCaretPosition(elemId, caretPos)
{
 var elem = document.getElementById(elemId);
 if (elem)
 {
  if (typeof elem.createTextRange != 'undefined')
  {
   var range = elem.createTextRange();
   range.move('character', caretPos);
   range.select();
  }
  else
  {
   if (typeof elem.selectionStart != 'undefined')
    elem.selectionStart = caretPos;
   elem.focus();
  }
 }
}
person Alexander Gavriliuk    schedule 31.05.2018

HTMLInputElement. setSelectionRange (selectionStart, selectionEnd);

// References
var e = document.getElementById( "helloworldinput" );

// Move caret to beginning on focus
e.addEventListener( "focus", function( event )
{
    // References
    var e = event.target;

    // Action
    e.setSelectionRange( 0, 0 );            // Doesn’t work for focus event
    
    window.setTimeout( function()
    {
        e.setSelectionRange( 0, 0 );        // Works
        //e.setSelectionRange( 1, 1 );      // Move caret to second position
        //e.setSelectionRange( 1, 2 );      // Select second character

    }, 0 );

}, false );

Совместимость с браузером (только для типов: текст, поиск, URL, телефон и пароль): https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange#Specifications

person Starboy    schedule 20.12.2020

person    schedule
comment
Uncaught TypeError: объект [объект HTMLInputElement] не имеет метода startWith - person bobpaul; 03.09.2011
comment
@bobpaul: tID должен быть идентификатором элемента, а не самим объектом элемента. Если вы передаете объект element, вы можете просто удалить 2 первые строки в этом методе, и он будет работать. - person awe; 25.11.2011