2

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

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

var autocomplete_values=["hello","dude","rubber","ducky"];

      $(".autocomplete").typeahead({
        source:autocomplete_values
      });

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

我完全不知道从哪里开始。在此先感谢您的帮助。

4

2 回答 2

3

使用绝对定位和虚拟元素,您可以非常准确地完成此操作。

我解决这个问题的方法是使用一个包含输入当前值的虚拟(不可见)内联元素。确保此元素具有完全相同的字体设置,我们可以轻松测量其宽度,然后我们可以使用它来抵消自动完成值。

输入字段和自动完成元素都绝对定位在相对定位的容器中,因此它们重叠。我给自动完成一个低于输入字段的 z-index 并使输入的背景透明,因此自动完成不会干扰单击输入字段。

我使用 text-indent 将自动完成文本定位在右侧,但您也可以使用 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 上运行的示例。

于 2012-10-15T21:43:17.330 回答
2

我将创建一个隐藏的 inline-block 元素,其内容反映了文本框的内容。

伪:

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

一旦你完成了这项工作,你只需进行一些测量和一些数学运算,就可以将智能感知弹出框准确定位在文本框上你想要的位置。

例如,您可以通过根据输入元素的宽度修改内联元素宽度来获得智能感知框的 offsetleft:

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

获得顶峰可能会更难一些,但没有什么是破解不了的。

于 2012-10-15T20:22:39.267 回答