简体   繁体   English

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

[英]Javascript get the absolute position (in px) of a caret in a input text or textarea

I'm trying to develop an autocomplete that actually positions itself underneath the caret position in an input text and/or textarea instead of just underneath the element. 我正在尝试开发一种自动完成功能,该功能实际上会将其自身定位在输入文本和/或textarea中的插入符号位置下方,而不是仅位于元素下方。 A bit like most IDEs. 有点像大多数IDE。

I'm currently using the Twitter bootstrap typeahead and I'm seeking to modify it. 我目前正在使用Twitter Bootstrap typea,并且正在寻求对其进行修改。 I prepared a JS BIN if you got an idea: http://jsbin.com/welcome/34949/edit With basic syntax: 如果您有想法,我准备了一个JS BIN: http : //jsbin.com/welcome/34949/edit使用基本语法:

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

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

Question How do I get the absolute position in pixels of a caret in an input text and/or a textarea? 问题如何获得输入文本和/或文本区域中插入符号的绝对位置?

I have absolutely no idea where to start. 我完全不知道从哪里开始。 Thanks in advance for your help. 在此先感谢您的帮助。

I would create a hidden inline-block element whose contents mirror that of the textbox. 我将创建一个隐藏的inline-block元素,其内容与文本框的内容相同。

Pseudo: 伪:

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

Once you've got that working, you're just aa few measurements and some math away from positioning your intellisense popup box exactly where you want it over your textbox. 一旦完成该工作,您只需进行一些测量和一些数学运算即可将智能感知弹出框准确定位在文本框上所需的位置。

For example, you could get the offsetleft for your intellisense box by modding your inline-element width by your input element's width: 例如,您可以通过用输入元素的宽度修改行内元素的宽度来获取智能感知框的offsetleft:

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

Getting the top might be a little tougher, but nothing a little hacking at couldn't solve. 获得最高职位可能要困难一些,但是没有什么可以解决的。

Using absolute positioning and a dummy element, you can accomplish this quite accurately. 使用绝对定位和虚拟元素,您可以非常准确地完成此操作。

The way I approached this is by having a dummy (invisible) inline element containing the current value of the input. 我解决此问题的方法是让一个虚拟(不可见)内联元素包含输入的当前值。 Making sure that this element has the exact same font setup, we can easily measure its width, which we can then use to offset the auto-complete value. 确保此元素具有完全相同的字体设置,我们可以轻松地测量其宽度,然后将其用于抵消自动完成值。

Both the input field and the autocomplete element are absolutely positioned in a relatively positioned container, so they overlap. 输入字段和自动完成元素都绝对位于相对放置的容器中,因此它们重叠。 I gave the autocomplete a z-index lower than the input field and made the input's background transparent so auto-complete does not interfere with clicking the input field. 我给自动完成功能提供了一个比输入字段低的z索引,并使输入背景透明,因此自动完成功能不会干扰单击输入字段。

I used text-indent to get the autocomplete text positioned right, but you can also use the left property to actually move the element. 我使用text-indent将自动完成文本放置在右侧,但是您也可以使用left属性实际移动元素。

HTML HTML

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

CSS 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 JavaScript的

(using jQuery, but should get the point accross) (使用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');
    }
);

I've got an example running on jsfiddle. 我有一个在jsfiddle上运行的示例

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

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