Получить позицию курсора (в символах) в поле ввода текста

Как я могу получить позицию курсора в поле ввода?

Я нашел несколько бит и кусочков через Google, но ничего пуленепробиваемого.

в основном что-то вроде плагина jQuery было бы идеальным, поэтому я мог бы просто сделать

$("#myinput").caretPosition()

8 ответов


проще обновить:

использовать field.selectionStart пример в этом ответе.

спасибо @commonSenseCode за указание на это.


ответ:

нашел это решение. Не основанный на jquery, но нет проблем интегрировать его в jquery:

/*
** Returns the caret (cursor) position of the specified text field.
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {

  // Initialize
  var iCaretPos = 0;

  // IE Support
  if (document.selection) {

    // Set focus on the element
    oField.focus();

    // To get cursor position, get empty selection range
    var oSel = document.selection.createRange();

    // Move selection start to 0 position
    oSel.moveStart('character', -oField.value.length);

    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }

  // Firefox support
  else if (oField.selectionStart || oField.selectionStart == '0')
    iCaretPos = oField.selectionStart;

  // Return results
  return iCaretPos;
}

хороший, большое спасибо Максу.

я обернул функциональность в его ответе в jQuery, если кто-то хочет ее использовать.

(function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if ('selectionStart' in input) {
            // Standard-compliant browsers
            return input.selectionStart;
        } else if (document.selection) {
            // IE
            input.focus();
            var sel = document.selection.createRange();
            var selLen = document.selection.createRange().text.length;
            sel.moveStart('character', -input.value.length);
            return sel.text.length - selLen;
        }
    }
})(jQuery);

ОЧЕНЬ ПРОСТО

обновил ответ

использовать selectionStart, это совместим со всеми основными браузерами.

document.getElementById('foobar').addEventListener('keyup', e => {
  console.log('Caret at: ', e.target.selectionStart)
})
<input id="foobar" />

Update: это работает только тогда, когда тип не определен или type="text" на входе.


есть очень простое решение. Попробуйте следующий код с проверенным результатом-

<html>
<head>
<script>
    function f1(el) {
    var val = el.value;
    alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
    <button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>

Я даю вам fiddle_demo


   (function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if (document.selection) {
            // IE
           input.focus();
        }
        return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
     }
   })(jQuery);

есть хороший плагин для этого: Плагин Каретки

затем вы можете получить позицию с помощью $("#myTextBox").caret() или установите его через $("#myTextBox").caret(position)


здесь есть несколько хороших ответов, но я думаю, что вы можете упростить свой код и пропустить проверку на inputElement.selectionStart поддержка: он не поддерживается только на IE8 и более ранних версиях (см. документация) что составляет менее 1% от текущего использование браузера.

var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;

// and if you want to know if there is a selection or not inside your input:

if (input.selectionStart != input.selectionEnd)
{
    var selectionValue =
    input.value.substring(input.selectionStart, input.selectionEnd);
}

возможно, Вам нужен выбранный диапазон в дополнение к позиции курсора. Вот простая функция, вам даже не нужен jQuery:

function caretPosition(input) {
    var start = input[0].selectionStart,
        end = input[0].selectionEnd,
        diff = end - start;

    if (start >= 0 && start == end) {
        // do cursor position actions, example:
        console.log('Cursor Position: ' + start);
    } else if (start >= 0) {
        // do ranged select actions, example:
        console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
    }
}

предположим, вы хотите вызвать его на входе всякий раз, когда он меняется или мышь перемещает позицию курсора (в этом случае мы используем jQuery .on()). По соображениям производительности, может быть хорошей идеей добавить setTimeout() или что-то вроде подчеркивания _debounce() если события вливаются:

$('input[type="text"]').on('keyup mouseup mouseleave', function() {
    caretPosition($(this));
});

вот скрипка, если вы хотите попробовать: https://jsfiddle.net/Dhaupin/91189tq7/