如何在文本框中获取插入符的(x,y)像素坐标?

37

我正在使用jQuery,并尝试找到一种跨浏览器的方法来获取<textarea>input 元素中插入符的像素坐标,以便我可以在该位置周围放置一个绝对定位的

元素。

是否有一些jQuery插件或JavaScript代码片段可以实现这个功能?

2个回答

44

我在寻找一个与meteor-autocomplete兼容的文本区域插件,于是我评估了GitHub上的8个插件。迄今为止,胜利者是来自Componenttextarea-caret-position插件。

特点

  • 像素精度
  • 完全无依赖
  • 浏览器兼容性: Chrome,Safari,Firefox(尽管它有两个 漏洞),IE9+;可能在Opera,IE8或更早版本中可以工作,但未经测试
  • 支持任何字体系列和大小,以及文本转换
  • 文本区域可以具有任意填充或边框
  • 不会被文本区域的水平或垂直滚动条所困惑
  • 支持文本中硬回车、制表符(除IE外)和连续空格
  • 在文本区域中正确定位长于列的行
  • 单词太长时,在折行时不会在空白处出现"幽灵"位置

这是一个演示 - http://jsfiddle.net/dandv/aFPA7/

enter image description here

工作原理

创建一个镜像 <div> 并在屏幕外设置其样式与 <textarea> 完全相同。然后,将文本框中光标之前的文本复制到 div 中,并在其右侧插入一个 <span>。接着,将 span 的文本内容设置为文本框中剩余的文本,以忠实地再现 faux div 中的换行。

这是唯一保证处理所有关于长行包装的边缘情况的方法。GitHub 也使用它来确定其@用户下拉菜单的位置。


3
我刚注意到在“随机”的文字之间,你插入了Carly Rae Jepsen的歌曲《Call Me Maybe》(http://www.youtube.com/watch?v=fWNaR-rxAic)的歌词。不过好的建议!但是在最近的Chrome版本中有一个错误。你从一行开头选择到中间。然后你点击行的开头。红色光标不会移动。 - Ismael Miguel
@IsmaelMiguel - 很高兴你注意到了这首歌 :) 关于问题,你能否请在GitHub上提交?谢谢! - Dan Dascalescu
我刚刚注意到,我拼错了“random”:/ 而且我还有更糟糕的消息:IE11上的幽灵选择又回来了。 - Ismael Miguel
对我来说不起作用,我刚刚打开了演示JSFiddle,在中间某个地方单击,插入符似乎偏移了1行。 - stenwolf

1
注意:本答案描述如何获取文本光标/插入符的字符坐标。要查找像素坐标,您需要进一步扩展此功能。
首先要记住的是,光标可以处于三种状态:
- 特定位置的常规插入光标 - 具有某个有界区域的文本选择 - 非活动状态:textarea没有焦点。尚未使用。
IE模型使用对象document.selection,从中我们可以获取TextRange对象,从而访问选择和光标位置。
FF模型/Opera使用方便的变量[input].selectionStart和selectionEnd。
两种模型都将常规活动光标表示为零宽度选择,其左边界为光标位置。

如果输入字段没有焦点,您可能会发现两者都没有设置。 我已经成功地使用以下代码在当前光标位置插入文本,并替换当前选择(如果存在)。 根据具体的浏览器,结果可能有所不同。

function insertAtCursor(myField, myValue) {

/* selecion model - ie */
if (document.selection) {
  myField.focus();
  sel = document.selection.createRange();
  sel.text = myValue;
}

/* field.selectionstart/end  firefox */ 
else if (myField.selectionStart || myField.selectionStart == '0' ) {

  var startPos = myField.selectionStart;
  var endPos = myField.selectionEnd;
  myField.value = myField.value.substring(0, startPos)
    + myValue
    + myField.value.substring(endPos, myField.value.length);

  myField.selectionStart = startPos + myValue.length;
  myField.selectionEnd = startPos + myValue.length;
  myField.focus();
} 

// cursor not active/present
else {
  myField.value += myValue;
}

Bug Note: 链接在顶部段落中没有被正确标记。
选择对象:http://msdn.microsoft.com/en-us/library/ms535869(VS.85).aspx TextRange 对象:http://msdn.microsoft.com/en-us/library/ms535872(VS.85).aspx

Component.io团队已经开发了一个插件来计算textarea中插入符的(x, y)坐标。它几乎完美运行,但IE存在一个问题。您能提供帮助吗? - Dan Dascalescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接