输入类型文本(不是textarea)中的插入位置(以像素为单位)

时间:2012-11-12 16:28:10

标签: javascript html textinput caret

更新Get cursor or text position in pixels for input element的副本。

TL; DR - 使用非常轻量级且功能强大的textarea-caret-position 组件库,该库现在也支持<input ype="text">。在http://jsfiddle.net/dandv/aFPA7/

进行演示

有没有办法知道插入符号在HTML文本字段中的位置?

<input type='text' /> 

我想根据插入符的位置以像素为单位(并重新定位)div。

  

注意 :我不想知道字符或<textarea>中的位置。我想知道<input>元素中的位置(

6 个答案:

答案 0 :(得分:17)

使用不可见的虚假元素

您可以使用绝对定位的不可见(使用visibility而不是display)faux元素来完成此操作,该元素具有与输入文本框(字体,左边框和左边距)相同的CSS属性

very short and easy to understand JSFiddle是此脚本应如何工作的起点 它可以在Chrome和Firefox中使用。而且it seems它也应该在IE9 +中运行。

Internet Explorer 8(及以下)将need some additional code从输入文本框中的文本开头获取插入位置。我甚至在顶部添加了一个仪表,每隔10个像素显示一条线,这样你就能看出它是否正确测量。请注意,线条位于1,11,21,......像素位置。

这个例子实际上是将文本框中的所有文本放到插入位置并将其放在虚假元素中,然后以像素为单位测量其宽度。 这会让您偏离文本框的左侧。

当它将文本复制到虚假元素时,它也会用非破坏元素替换普通空格,这样它们实际上会被渲染,否则如果你在空格后立即放置插入符号就会出错:

var faux = $("#faux");
$("#test").on("keyup click focus", function(evt) {
    // get caret offset from start
    var off = this.selectionStart;

    // replace spaces with non-breaking space
    faux.text(this.value.substring(0, off).replace(/\s/g, "\u00a0"));
});​

请注意虚假的正确尺寸

  • 填充
  • 边界
  • 余量

已被删除以获得正确的值,否则元素将太宽。元素的框必须在它包含的文本之后结束。

Caret从输入框开始的像素位置很容易得到:

faux.outerWidth();

问题

但是有一个问题。我不确定当文本框中的文本滚动时(如果太长)并且插入符号不在文本的最末端但介于其间的某个位置时如何处理情况...如果它在结尾处则插入位置始终处于可能的最大位置(输入宽度减去右侧尺寸 - 填充,边框,边距)。

我不确定是否可以在文本框中获取文本滚动位置?如果可以,那么即使这个问题也可以解决。但我不知道有任何解决方案...

希望这有帮助。

答案 1 :(得分:4)

根据我上面的评论,我想以下内容应该有效。

为了显示我省略格式化的原则,因此可能需要将元素(id =“spacer”)颜色设置为#FFFFFE,或者可以添加一些前导空格的像素......但是carret会按比例移动现在 - 只要id的测试和spacer使用相同的字体。

当然我们不知道 [px] 中的距离,但我们能够定位内容(一个carret)在这种情况下)完全符合比例字体的宽度,所以如果这是最终目标(如 OP line 3 中提到的那样),那么.... voi拉!

<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <script type="text/javascript">
            function adjust()
            {
                document.getElementById('spacer').innerHTML=document.getElementById('test').value;
            }
        </script>
        <p>
            <input name="test" id="test" type="text" onkeyup="adjust()" /> Test <br />
            <span id="spacer"></span>^here
        </p>
    </body>
</html>

<强>更新

<span id="spacer" style="color: #FFFFFF"></span>

这将使间隔物在白色背景上不可见,但尚未阻止用户通过选择span元素突出显示间隔文本。留下使间隔物不可选的任务 - 有一个很好的解决方案here

答案 2 :(得分:2)

答案 3 :(得分:1)

画布2D怎么样?它具有用于绘制测量文本的API。你可以用它。设置相同的字体,字体大小,你应该能够从文本框中测量字符串的宽度。

      $('body').append('<canvas id="textCanvas" width="100px" height="100px">I\'m sorry your browser does not support the HTML5 canvas element.</canvas>');
      var canvas = document.getElementById('textCanvas');
      var ctx = canvas.getContext('2d');
      ctx.measureText(text);
      var width = mes.width;

我使用这种解决方案来获取某些文本的宽度以在WebGL中绘制它。我工作得很好,但我从来没有测试过当文本对画布上下文很大时会发生什么,我想我会认为它很好,因为它是用于测量文本的API。但是你知道你应该完全检查出来! :)

答案 4 :(得分:0)

这是一个有效的例子http://jsfiddle.net/gPL3f/2/

为了找到插入符号的位置,我计算了输入中的字母,并将该值乘以1个字母的大小。

然后将div移动到该位置。

<html>
<head>
<style type="text/css">
body { font-size: 12px; line-height: 12px; font-family: arial;}
#box { width: 100px; height: 15px; position: absolute; top: 35px; left: 0px; background: pink;}
</style>
<script type="text/javascript" src="jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var letter_size = 6;
$("input[type='text']").keyup(function(e) {
    move_size = $(this).val().length * letter_size;
    $('#box').css({'left': move_size+'px'}); 
});
});
</script>

</head>
<body>
<input type="text" />
<div id="box">
/ move 
</div>
</body>
<html>

更新

$(document).ready(function(){
    var letter_size = 6;
    $("input[type='text']").keyup(function(e) {
        $('.hidden_for_width').text($(this).val());
        move_size = $('.hidden_for_width').width();
        $('#box').css({'left': move_size});
    });
});

添加了一个隐藏的容器,我从输入中插入了值。之后我得到那个容器的宽度并相应地移动我的DIV

答案 5 :(得分:-1)

function getCursorPosition (elem) {
  var pos = 0;  
  if (document.selection) {
    elem.focus ();
    var sele = document.selection.createRange();
    sele.moveStart('character', -elem.value.length);
    pos = sele.text.length;
  }
  else if (elem.selectionStart || elem.selectionStart == '0')
    pos = elem.selectionStart;
  return pos;
}​

getCursorPosition(document.getElementById('textbox1'))