获取文本输入字段中的光标位置(以字符为单位)

IT技术 javascript jquery html
2021-01-11 09:45:32

如何从输入字段中获取插入符号位置?

我通过谷歌找到了一些零碎的东西,但没有防弹。

基本上像 jQuery 插件这样的东西是理想的,所以我可以简单地做

$("#myinput").caretPosition()
6个回答

更简单的更新:

field.selectionStart 在此答案中使用示例

感谢@commonSenseCode 指出这一点。


旧答案:

找到了这个解决方案。不是基于 jquery,但将其集成到 jquery 没有问题:

/*
** Returns the caret (cursor) position of the specified text field (oField).
** 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.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;

  // Return results
  return iCaretPos;
}
chrome 和 firefox 总是为 0
2021-03-13 09:45:32
else if (oField.selectionStart || oField.selectionStart == '0') 可能 else if (typeof oField.selectionStart==='number')
2021-03-15 09:45:32
你在 IE 上测试吗?整个 if 部分仅在 IE 上执行。在 IE 中只有一个全局选择,这就是为什么它是document.selection,不是field.selection或什么的。此外,可以在 IE 7 中(不知道在 8+ 中是否仍然可以)选择某些内容,然后在不丢失选择的情况下按 Tab 键离开该字段。这样,当文本被选中但字段未聚焦时,document.selection返回零选择。这就是为什么,作为此错误的解决方法,您必须在阅读document.selection.
2021-04-01 09:45:32
“oField.focus()”的概念是什么?没有这条线它对我有用。如果在输入上使用模糊事件并在回调中执行该函数,请小心。
2021-04-03 09:45:32

使用selectionStart. 与所有主要浏览器兼容

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

这仅在未定义类型type="text"type="textarea"输入时有效。

很棒,但当输入类型为数字时,在 Firefox 或 Chrome 中不起作用。
2021-03-10 09:45:32
@JJJ 属性“selectionStart”在“HTMLElement”类型上不存在。
2021-03-15 09:45:32
如果我使用鼠标更改位置,它不会打印在控制台中。有办法解决吗?
2021-03-22 09:45:32
@EugeneBarsky 只需为单击事件添加一个新的事件侦听器。您可以随时检查该.selectionStart属性 ( document.getElementById('foobar').selectionStart),它不必位于事件侦听器中。
2021-03-22 09:45:32
@MojioMS 这确实作为 HTMLInputElement 的一部分存在,正如已经指出的那样,如果目标是 text 类型或 textarea 类型,它将起作用
2021-04-07 09:45:32

如果有人想使用它,我已将bezmax 答案中的功能包装到 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);
当输入为数字类型时,Firefox 在 input.selectionStart 上生成 NS_ERROR_FAILURE,将其包装在 try {} catch {}?
2021-03-23 09:45:32
@Mic 不,不在 jQuery 插件中。在插件中this是指一个完整的包装集。他的代码仍然是错误的,它应该只是this.get(0). 他的代码可能仍然有效,因为重新包装包装的集合什么也没做。
2021-03-26 09:45:32
这给了我错误的信息。我在娱乐文本时正在查看光标位置。我的小提琴证明了这一点: jsfiddle.net/fallenreaper/TSwyk
2021-03-28 09:45:32
如果您添加该功能的用法,对新蜜蜂会很好
2021-04-03 09:45:32
input = $(this).get(0)一样input = this吗?
2021-04-04 09:45:32

得到了一个非常简单的解决方案尝试使用以下代码验证结果-

<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

slice是一个相对昂贵的操作,它不会给这个“解决方案”增加任何东西——el.selectionStart相当于你切片的长度;只是返回。此外,其他解决方案更复杂的原因是因为它们处理其他不支持selectionStart.
2021-03-13 09:45:32
@user2782001:我说错了——我主要关心的是函数名称。f1与“user2782001”一样有意义。😉
2021-03-18 09:45:32
我已经辞去了工作,我不得不使用像这样的变量名称的代码。
2021-03-27 09:45:32
@Michael Scheper - 你的意思是元素的“el”和value的“val”?这些很常见...
2021-03-29 09:45:32

现在有一个很好的插件:The Caret Plugin

然后您可以使用$("#myTextBox").caret()或通过设置获取位置$("#myTextBox").caret(position)

插入符号插件似乎是用于 textarea 元素而不是输入
2021-04-01 09:45:32
好吧,我让它为 <input type="text" id="myTextBox"/> 工作并使用上面的代码。
2021-04-07 09:45:32