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

Posted

技术标签:

【中文标题】获取文本输入字段中的光标位置(以字符为单位)【英文标题】:Get cursor position (in characters) within a text Input field 【发布时间】:2011-02-23 05:44:58 【问题描述】:

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

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

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

$("#myinput").caretPosition()

【问题讨论】:

尝试搜索“光标位置”,这会给你带来更多的点击率,以及关于 SO 的一些主题。 How to get cursor position in textarea? 的可能副本。另见:FieldSelection plugin @CMS 在<input> 中查找位置比在<textarea> 中查找位置要简单得多。 @AndrewMao:如果滚动文本并且插入符号超过 size 个字符,则难度会更大。 @alec:我同意搜索光标而不是插入符号可能会产生更多结果。正如在别处指出的那样,我了解到 caret 是更合适的术语。 cursor 表示任何内容中的位置,而 caret 表示特定于文本中的位置。 【参考方案1】:

更新更轻松:

使用field.selectionStartexample in this answer。

感谢@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;

【讨论】:

else if (oField.selectionStart || oField.selectionStart == '0') 可能是else if (typeof oField.selectionStart==='number') “oField.focus()”的概念是什么?没有这条线它对我有用。如果您在输入上使用模糊事件并在回调中执行该函数,请小心。 你是在 IE 上测试吗?整个 if 部分仅在 IE 上执行。在 IE 中只有一个全局选择,这就是为什么它是 document.selection,而不是 field.selection 之类的。此外,在 IE 7 中(不知道在 8+ 中是否仍然可能)可以选择某些内容,然后 TAB 退出该字段而不会丢失选择。 This way, when the text is selected but the field is not focused, document.selection returns zero selection.这就是为什么,作为此错误的解决方法,您必须在阅读 document.selection 之前专注于元素。 chrome 和 firefox 总是为 0【参考方案2】:

使用selectionStart。是compatible with all major browsers。

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

这仅适用于未定义类型或在输入上定义type="text"type="textarea"

【讨论】:

如果我使用鼠标改变位置,它不会打印在控制台中。有办法解决吗? @EugeneBarsky 只需为点击事件添加一个新的事件监听器。您可以随时检查.selectionStart 属性 (document.getElementById('foobar').selectionStart),它不必位于事件侦听器中。 很棒,但在输入类型为数字时在 Firefox 或 Chrome 中不起作用。 @JJJ 属性 'selectionStart' 在类型 'htmlElement' 上不存在。 @MojioMS 这确实作为 HTMLInputElement 的一部分存在,正如已经指出的那样,如果目标是文本类型或文本区域类型,它将起作用【参考方案3】:

如果有人想使用它,我已经将 bezmax's answer 中的功能包装到 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);

【讨论】:

input = $(this).get(0)input = this不一样吗? @Mic 不,不在 jQuery 插件中。在插件中this 指的是完整包装的集合。他的代码仍然是错误的,它应该只是this.get(0)。他的代码可能仍然有效,因为重新包装一个包装集没有任何作用。 这给了我错误的信息。我在娱乐文本时正在查看光标位置。我的小提琴证明了这一点:jsfiddle.net/fallenreaper/TSwyk 当输入是数字类型时,Firefox 在 input.selectionStart 上生成一个 NS_ERROR_FAILURE,将其包装在 try catch 中? 如果你添加函数的用法对新蜜蜂来说会很好【参考方案4】:

有一个非常简单的解决方案。 尝试以下代码验证结果-

<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的其他浏览器。 我已经辞去了工作,因为我不得不使用这样的变量名来处理代码。 @Michael Scheper - 你的意思是“el”代表元素,“val”代表价值?这些很常见...... @user2782001:我说错了——我主要关心的是函数名。 f1 与 'user2782001' 一样有意义。 ?【参考方案5】:

现在有一个不错的插件:The Caret Plugin

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

【讨论】:

插入符号插件似乎适用于 textarea 元素而不是输入 好吧,我让它为 工作并使用上面的代码。【参考方案6】:
   (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);

【讨论】:

【参考方案7】:

这里发布了一些很好的答案,但我认为您可以简化代码并跳过对inputElement.selectionStart 支持的检查:它不仅在 IE8 和更早版本上受支持(请参阅documentation),它表示小于 1当前browser usage的百分比。

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

【讨论】:

【参考方案8】:

除了光标位置之外,您可能还需要一个选定范围。这是一个简单的函数,你甚至不需要 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/

【讨论】:

【参考方案9】:

const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets  inputs .
var swch;
// swch  if corsur is active in inputs defaulte is false .
var isSelect = false;

var crnselect;
// on focus
function setSwitch(e) 
  swch = e;
  isSelect = true;
  console.log("set Switch: " + isSelect);

// on click ev
function setEmoji() 
  if (isSelect) 
    console.log("emoji added :)");
    swch.value += ":)";
    swch.setSelectionRange(2,2 );
    isSelect = true;
  


// on not selected on input . 
function onout() 
  // الافنت  اون كي اب 
  crnselect = inpC.selectionStart;
  
  // return input select not active after 200 ms .
  var len = swch.value.length;
  setTimeout(() => 
   (len == swch.value.length)? isSelect = false:isSelect = true;
  , 200);
<h1> Try it !</h1>
    
		<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
		<input type="text" onfocus = "setSwitch(this)"  onfocusout = "onout()"  id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>

【讨论】:

【参考方案10】:

解决办法是.selectionStart:

var input = document.getElementById('yourINPUTid');
input.selectionEnd = input.selectionStart = yourDESIREDposition;
input.focus();

如果没有分配.selectionEnd,则会选择一些文本(S-->E)。

失去焦点时需要.focus();当您触发代码时(onClick)。

我只在 Chrome 中测试过。

如果您想要更复杂的解决方案,则必须阅读其他答案。

【讨论】:

以上是关于获取文本输入字段中的光标位置(以字符为单位)的主要内容,如果未能解决你的问题,请参考以下文章

获取输入元素的光标或文本位置(以像素为单位)

获取输入元素的光标或文本位置(以像素为单位)

获取光标书写位置

获取textarea文本框所选字符光标位置索引,以及选中的文本值;textarea高度自适应,随着内容增加高度增加;获取输入框中的光标位置

当用户单击按钮时,将文本字符串添加到输入字段中(在光标位置)

如何将光标设置到 Internet Explorer 中文本 INPUT 字段的字符串值中的特定位置?