37

我正在使用 jQuery 并试图找到一种跨浏览器的方式来获取<textarea>s 和input盒子中插入符号的像素坐标,这样我就可以在这个位置周围放置一个绝对定位的 div。

有一些 jQuery 插件吗?或者 JavaScript 片段来做到这一点?

4

2 回答 2

42

我已经为meteor-autocomplete寻找一个 textarea caret 坐标插件,所以我评估了 GitHub 上的所有 8 个插件。到目前为止,获胜者是来自Component的 textarea-caret-position

特征

  • 像素精度
  • 没有任何依赖
  • 浏览器兼容性:Chrome、Safari、Firefox(尽管有两个 错误)、IE9+;可以工作,但未在 Opera、IE8 或更早版本中测试
  • 支持任何字体系列和大小,以及文本转换
  • 文本区域可以有任意填充或边框
  • 不会被文本区域中的水平或垂直滚动​​条弄糊涂
  • 支持硬回车、制表符(IE 除外)和文本中的连续空格
  • 比文本区域中的列长的行上的正确位置
  • 换行时在行尾的空白处没有“幽灵”位置

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

在此处输入图像描述

这个怎么运作

镜子<div>是在屏幕外创建的,其样式与<textarea>. 然后,直到插入符号的文本区域的文本被复制到 div 中,并在<span>其后插入 a。然后,将 span 的文本内容设置为 textarea 中文本的其余部分,以便忠实地再现假 div 中的换行。

这是保证处理所有与换行长线有关的边缘情况的唯一方法。GitHub 也使用它来确定其@user 下拉列表的位置

于 2014-03-17T04:00:08.587 回答
0

注意:此答案描述了如何获取文本光标/插入符号的字符坐标。要找到像素坐标,您需要进一步扩展它。

首先要记住的是光标可以处于三种状态

  • 在特定位置的常规插入光标
  • 具有特定边界区域的文本选择
  • 未激活:textarea 没有焦点。没有被使用。

IE 模型使用 Object document.selection,从中我们可以得到一个TextRange对象,它使我们能够访问选择,从而访问光标位置。

FF 模型/Opera 使用方便的变量 [input].selectionStart 和 selectionEnd。

两种模型都将常规原生光标表示为零宽度选择,左边界是光标位置。

如果输入字段没有焦点,您可能会发现两者都没有设置。我使用以下代码在当前光标位置插入一段文本取得了很好的成功,同时替换了当前选择(如果存在)。取决于确切的浏览器,YMMV。

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

错误说明:链接未在顶部正确标记。

选择对象: http: //msdn.microsoft.com/en-us/library/ms535869
(VS.85).aspx TextRange 对象:http://msdn.microsoft.com/en-us/library/ms535872(VS.85) 85).aspx

于 2008-08-27T11:50:06.080 回答