将文本输入定位在 textarea 的光标位置之上(javascript、Textarea 自动完成)

Posted

技术标签:

【中文标题】将文本输入定位在 textarea 的光标位置之上(javascript、Textarea 自动完成)【英文标题】:Positioning a text input on top of a textarea's cursor position (javascript, Textarea autcompleting) 【发布时间】:2012-10-10 07:50:00 【问题描述】:

我想做一个自动完成功能,如果有人键入“@”,他们会得到一个自动完成的姓名列表。

我正在使用 jQueryUI 自动完成功能,我的解决方案 (http://jsfiddle.net/aUfrz/22/) 的唯一问题是可自动完成的文本输入需要放置在 textarea 光标位置的顶部,而不是当前位置的右侧。

这是我在 JSFiddle 中的 JS:

$(document.body).on('keypress', 'textarea', function(e) 
   var names = [
        "johnny",
        "susie",
        "bobby",
        "seth"
    ],
    $this=$(this),
    char = String.fromCharCode(e.which);

    if(char == '@') 
       console.log('@ sign pressed');
       var input=$('<input style="position:relative; top:0px; left:0px;background:none;border:1px solid red" id="atSign" >');
       $this.parent().append(input);
       input.focus();
       input.autocomplete(
        source: names,
        select: function (event, ui) 
            console.log('value selected'+ui.item.value);
            //$this.val('@'+ui.item.value);
            $this.insertAtCaret(ui.item.value);
            $this.focus();
            input.remove();
         //select
    );  //autocomplete
   //if 
); // keypress

html

<textarea></textarea>​

请注意,我在此处NOT显示了一个 jQuery 插件,用于在插入符号位置插入选定的自动完成建议:insertAtCaret(),我在此 other SO question 找到了它。

【问题讨论】:

您的意思是要获取插入符号的像素坐标,然后将输入定位在那里?我不确定是否可以获得插入符号的像素坐标。 这似乎是一种解决方案,为什么我们不能得到这些坐标? 因为通常不需要此信息,因此无法通过 DOM 访问。您可以尝试将每个字符的像素宽度乘以插入符号的字符偏移量,以获得文本区域内插入符号的像素偏移量。 @Asad 谢谢你,你能在回答中提供这个建议吗? 我正在努力在小提琴中实现这一点,并将很快发布答案。如果有人击败我,欢迎他们发布。 【参考方案1】:

获取插入符号位置的一种方法是将每个字符的像素宽度乘以插入符号的字符偏移量。 Here 是一个有点粗略的例子。与 textarea 的 x 偏移量计算如下:

e.target.value.length*13

编辑:Here 是一个大大改进的版本。一个重要的发现是,在monotype字体中,宽高比是8/13。

在下面的截图中,你可以看到当我按下@时,输入出现在插入符号的位置。

这是 Chrome 中的屏幕截图,显示了相同的行为

【讨论】:

每次添加名称时,文本输入仍然相对于光标移动,简单来说,最简单的方法是将自动完成建议附加到文本区域的左下角。这不会太可怕。另外,您知道如何隐藏文本输入以使其没有边框吗? 就文本输入移动而言,我已在第二个小提琴中修复了该问题。试试this。输入显示为自动完成,然后在您选择一个值后消失。 它移动到插入符号的位置,如果这就是你的意思。这不是你的要求吗? 看起来它在 Chrome 与 IE 上的行为不同。您是否可以尝试也尝试摆脱焦点上的文本输入边框 CSS?我想让输入透明,这样用户就不会意识到他们实际上是在不同的框中输入。非常感谢您的帮助,并愿意接受您的回答,但还是有点偏离... 我认为定位部分的质量不够高,无法接受。我想我只会将输入和建议附加到文本区域的底部。公平地说,最初没有询问样式。【参考方案2】:

这个other SO answer 提到了这个漂亮的jQuery 插件asuggest 是我要使用的。感谢@asad 的帮助。

这是使用 asuggest() 的最终产品的 JSFiddle:http://jsfiddle.net/trpeters1/xjyTW/2/

这是来自这个 JSFiddle 的 JS:

$.fn.asuggest.defaults.delimiters = "@";
$.fn.asuggest.defaults.minChunkSize = "0";  

$(document.body).on('keypress', 'textarea', function(e) 
  var names = [
    "johnny",
    "susie",
    "bobby",
    "seth"
  ],
  $this=$(this),
  char = String.fromCharCode(e.which);

   if(char == '@') 
     $this.asuggest(names);
     var v='';
     if($this.click())  console.log('clicked textarea');           
       v=$this.val(); console.log('texarea value'+v);           
       for(var i=0; i<names.length;i++ ) 
         if(v.indexOf('@'+names[i]) != -1)
           names.splice(i,1);  console.log('names spliced away: @'+names[i]);              
          // if indexOf
        //for
      //if click
    //if @
); //keypress​

HTML:

<textarea></textarea>​

【讨论】:

以上是关于将文本输入定位在 textarea 的光标位置之上(javascript、Textarea 自动完成)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 textarea 文本更改上保留光标位置?

java按回车键,光标自动定位到下一个文本框中,

jQuery文本框输入格式限制valueChange replace光标移动问题

如果设置Div 编辑器的光标位置?

可编辑DIV 光标位置 处理

JavaFX:TextArea 光标移回新文本的第一行