简体   繁体   English

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

[英]How do I get the (x, y) pixel coordinates of the caret in text boxes?

I am using jQuery and trying to find a cross browser way to get the pixel coordinates of the caret in <textarea> s and input boxes such that I can place an absolutely positioned div around this location.我正在使用 jQuery 并试图找到一种跨浏览器的方式来获取<textarea>input框中插入符号的像素坐标,以便我可以在这个位置周围放置一个绝对定位的 div。

Is there some jQuery plugin?是否有一些 jQuery 插件? Or JavaScript snippet to do just that?或者 JavaScript 片段来做到这一点?

I've looked for a textarea caret coordinates plugin for meteor-autocomplete , so I've evaluated all the 8 plugins on GitHub. 我已经为meteor-autocomplete寻找了textarea插入符号插件,所以我已经评估了GitHub上的所有8个插件。 The winner is, by far, textarea-caret-position from Component . 到目前为止,胜利者是来自Component的 textarea-caret-position

Features 特征

  • pixel precision 像素精度
  • no dependencies whatsoever 没有依赖关系
  • browser compatibility: Chrome, Safari, Firefox (despite two bugs it has), IE9+; 浏览器兼容性:Chrome,Safari,Firefox(尽管有两个 漏洞 ),IE9 +; may work but not tested in Opera, IE8 or older 可以工作,但未在Opera,IE8或更早版本中测试过
  • supports any font family and size, as well as text-transforms 支持任何字体系列和大小,以及文本转换
  • the text area can have arbitrary padding or borders 文本区域可以具有任意填充或边框
  • not confused by horizontal or vertical scrollbars in the textarea 不会被textarea中的水平或垂直滚动​​条混淆
  • supports hard returns, tabs (except on IE) and consecutive spaces in the text 支持硬回车,标签(IE上除外)和文本中的连续空格
  • correct position on lines longer than the columns in the text area 在比文本区域中的列长的行上的正确位置
  • no "ghost" position in the empty space at the end of a line when wrapping long words 当包裹长词时,在行尾的空白处没有“鬼”位置

Here's a demo - http://jsfiddle.net/dandv/aFPA7/ 这是一个演示 - http://jsfiddle.net/dandv/aFPA7/

在此输入图像描述

How it works 这个怎么运作

A mirror <div> is created off-screen and styled exactly like the <textarea> . 镜像<div>在屏幕外创建,其样式与<textarea>完全相同。 Then, the text of the textarea up to the caret is copied into the div and a <span> is inserted right after it. 然后,直到插入符号的textarea文本被复制到div中,并在其后插入<span> Then, the text content of the span is set to the remainder of the text in the textarea, in order to faithfully reproduce the wrapping in the faux div. 然后,跨度的文本内容被设置为textarea中文本的剩余部分,以便忠实地再现人造div中的包装。

This is the only method guaranteed to handle all the edge cases pertaining to wrapping long lines. 这是保证处理与包装长行相关的所有边缘情况的唯一方法。 It's also used by GitHub to determine the position of its @ user dropdown. 它也被GitHub用来确定其@用户下拉列表的位置。

I don't think it can be done in every browser. 我不认为它可以在每个浏览器中完成。 Someone has done it in IE6, but it does not work in FF or Opera (AFAIK). 有人在IE6中完成了它,但它在FF或Opera(AFAIK)中不起作用。 Maybe you can get it to work in all the browsers. 也许你可以在所有浏览器中使用它。

Here's a blog post from 2005 . 这是2005年的博客文章

Note: this answer describes how to get the character co-ordinates of the text-cursor/caret. 注意:这个答案描述了如何获得text-cursor / caret的字符坐标 To find the pixel-co-ordinates, you'll need to extend this further. 要找到像素坐标,您需要进一步扩展。

The first thing to remember is that the cursor can be in three states 要记住的第一件事是光标可以处于三种状态

  • a regular insertion cursor at a specific position 在特定位置的常规插入光标
  • a text selection that has a certain bounded area 具有特定有界区域的文本选择
  • not active: textarea does not have focus. 不活跃:textarea没有焦点。 Has not been used. 尚未使用过。

The IE model uses the Object document.selection , from this we can get a TextRange object which gives us access to the selection and thus the cursor position(s). IE模型使用Object document.selection ,从中我们可以得到一个TextRange对象,它允许我们访问选择,从而访问光标位置。

The FF model/Opera uses the handy variables [input].selectionStart and selectionEnd. FF模型/ Opera使用方便的变量[input] .selectionStart和selectionEnd。

Both models represent a regular ative cursor as a zero-width selection, with the left bound being the cursor position. 两种模型都将常规活动光标表示为零宽度选择,左边界是光标位置。

If the input field does not have focus, you may find that neither is set. 如果输入字段没有焦点,您可能会发现两者都没有设置。 I have had good success with the following code to insert a piece of text at the current cursor location, also replacing the current selection, if present. 我使用以下代码取得了很好的成功,在当前光标位置插入一段文本,同时替换当前选择(如果存在)。 Depending on the exact browser, YMMV. 根据确切的浏览器,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;
}

Bug Note: links are not being correctly marked up in the top para. 错误注意:链接未在顶部参数中正确标记。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM