在文本框的光标位置上方放置一个文本输入框(JavaScript,文本框自动完成)

5
我希望制作一个自动完成功能,当用户输入“@”时,会出现一个自动完成列表来显示名字。
我正在使用jQueryUI的自动完成插件,但我的解决方案(http://jsfiddle.net/aUfrz/22/)唯一的问题是需要将可以自动完成的文本框放置在文本区光标位置上方,而不是当前右侧。
以下是我在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>​

请注意,我这里没有展示一个jQuery插件,该插件用于将所选自动完成建议插入到插入符位置:insertAtCaret(),我在其他SO问题中发现了它。

你的意思是想要获取插入符号的像素坐标,然后将输入定位到那里吗?我不确定是否可能获取插入符号的像素坐标。 - Asad Saeeduddin
那似乎是一个解决方案,为什么我们不能得到那些坐标呢? - tim peterson
因为这些信息通常不需要,并且因此没有通过DOM进行访问。您可以尝试将每个字符的像素宽度乘以插入符号的字符偏移量,以获取文本区域内插入符号的像素偏移量。 - Asad Saeeduddin
@Asad 谢谢,你能把这个建议写成一个回答吗? - tim peterson
1
我正在努力在 Fiddle 上实现这个功能,并将很快发布答案。如果有人比我先完成了,他们可以随意发布。 - Asad Saeeduddin
2个回答

2
获取光标位置的一种方式是将每个字符的像素宽度乘以光标的字符偏移量。这里有一个相当简单的示例说明此方法。这里是演示。从文本区域计算出的x偏移量如下:
e.target.value.length*13

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

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

A screenshot showing how it looks in my browser.

这里是在Chrome中的截图,显示相同的行为

enter image description here


每次添加名称时,文本输入相对于光标仍在移动,为了简化事情,最好将自动完成建议附加到文本区域的左下角。这不会太糟糕。另外,您知道如何隐藏文本输入框,使其没有边框吗? - tim peterson
就文本输入移动而言,我已经在第二个 fiddle 中修复了它。请尝试这个。输入框会出现自动完成提示,一旦您选择了一个值,它就会消失。 - Asad Saeeduddin
它会移动到插入符号位置,如果这是您的意思的话。那不是您的要求吗? - Asad Saeeduddin
2
我不认为定位部分的质量足够高来接受。我想我只会将输入和建议附加到文本区域底部。说实话,样式方面最初并没有要求。 - tim peterson
@timpeterson,我刚刚下载了Chrome并测试了一下,它运行良好!你确定你使用的是我fiddle的最新版本吗? - Asad Saeeduddin
显示剩余3条评论

0

我将使用提到这个非常棒的jQuery插件asuggest其他SO答案。感谢@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>​

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