获取文本输入字段中的光标位置(以字符为单位)
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.selectionStart
example 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高度自适应,随着内容增加高度增加;获取输入框中的光标位置