Javascript获取插入符号在输入文本或文本区域中的绝对位置(以px为单位)



我正在尝试开发一个自动补全,它实际上将自己定位在输入文本和/或文本区域的插入符号位置下方,而不是元素下方。有点像大多数IDE。

我目前正在使用Twitter引导程序typeahead,我正在寻求修改它。如果你有想法,我准备了一个JS BIN:http://jsbin.com/welcome/34949/edit基本语法:

var autocomplete_values=["hello","dude","rubber","ducky"];
$(".autocomplete").typeahead({
source:autocomplete_values
});

问题如何获得输入文本和/或文本区域中插入符号的绝对位置(以像素为单位)?

我完全不知道从哪里开始。提前感谢您的帮助。

使用绝对定位和虚拟元素,可以非常准确地完成这一任务。

我处理这个问题的方法是使用一个包含输入的当前值的伪(不可见)内联元素。确保这个元素有完全相同的字体设置,我们可以很容易地测量它的宽度,然后我们可以使用它来抵消自动完成值。

输入字段和自动完成元素都绝对位于相对位置的容器中,因此它们重叠。我给了自动完成一个低于输入字段的z索引,并使输入的背景透明,这样自动完成就不会干扰点击输入字段。

我使用文本缩进来将自动完成的文本放置在右侧,但您也可以使用left属性来实际移动元素。

HTML

<div id="container">
<input type="text" id="foo">
<div id="ac"></div>
<span id="dummy"></span>
</div>

CSS

#container { position: relative; }
#foo, #ac, #dummy {
font-family: monospace;
font-size: 16px;
}
#foo, #ac {
position: absolute;
top: 0;
left: 0;
}
#foo {
z-index: 2;
border: solid 1px black;   
background: transparent;
}
#ac {   
top: 1px;
left: 2px;
z-index: 1;
color: #999;
}
#dummy { visibility: hidden; }

JavaScript

(使用jQuery,但应该得到交叉点)

$('#foo').keyup(function(event) {
//get autocomplete value
var autoComplete = dummyAutoComplete($(this).val());
//if a value is found, show it in #ac and adjust position
if (autoComplete !== null) {
//add in value and make visible
$('#ac').html(autoComplete).removeClass('hidden');
//dummy gets the same value as the input, to measure its width          
$('#dummy').html($(this).val());
//add autocomplete text-indent based on dummy width + some adjustmet
$('#ac').css('text-indent', $('#dummy').outerWidth() + 'px');       
} else {
//hide autocomplete                
$('#ac').html('').addClass('hidden');
}
);

我有一个在jsfiddle上运行的例子。

我会创建一个隐藏的内联块元素,其内容与文本框的内容镜像。

伪:

myTextBox.onkeyup = function(){
myInlineContainer.innerHTML = this.value
}

一旦你做到了这一点,你只需要进行一些测量和计算,就可以将你的intelligense弹出框准确地定位在你想要的文本框上。

例如,您可以通过将内联元素的宽度修改为输入元素的宽度来获得intelligense框的offsetleft:

intellisenceLeft = (myInlineContainer.offsetWidth % myTextBox.offsetWidth);

登顶可能有点困难,但没有什么是一点点黑客攻击无法解决的。

最新更新