Javascript 输入类型文本(非文本区域)中以像素为单位的插入符号位置
更新:的副本 TL;DR-使用极其轻量级和健壮的组件库,它现在也支持Javascript 输入类型文本(非文本区域)中以像素为单位的插入符号位置,javascript,html,textinput,caret,Javascript,Html,Textinput,Caret,更新:的副本 TL;DR-使用极其轻量级和健壮的组件库,它现在也支持。演示 有没有办法知道插入符号在HTML文本字段中的位置 <input type='text' /> 我想根据插入符号的位置以像素为单位定位(并重新定位)一个div 注意:我不想知道字符或中的位置。我想知道元素中像素的位置 使用不可见的人造元素 您可以通过使用绝对定位的不可见(使用可见性而不是显示)人造元素来实现这一点,该人造元素具有与输入文本框相同的CSS属性(字体、左边框和左填充) 这是该脚本如何工作的
。演示
有没有办法知道插入符号在HTML文本字段中的位置
<input type='text' />
我想根据插入符号的位置以像素为单位定位(并重新定位)一个div
注意:我不想知道字符或
中的位置。我想知道
元素中像素的位置
使用不可见的人造元素
您可以通过使用绝对定位的不可见(使用可见性
而不是显示
)人造元素来实现这一点,该人造元素具有与输入文本框相同的CSS属性(字体、左边框和左填充)
这是该脚本如何工作的起点。它可以在Chrome和Firefox中正常工作。它也可以在IE9+中工作 InternetExplorer8(及以下版本)需要从输入文本框中文本的开头获取插入符号位置。我甚至在顶部添加了一个米,每10像素显示一条线,这样你就可以看到它的测量是否正确。请注意,行在1、11、21、,。。。像素位置 本例所做的实际上是将文本框中的所有文本提取到插入符号位置,并将其放入faux元素中,然后以像素为单位测量其宽度这将使您从文本框的左侧偏移。 当它将文本复制到faux元素时,它也会将普通空格替换为非打断空格,因此如果您将插入符号放置在空格之后,它们实际上会被渲染,否则您会得到错误的位置:
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"));
});
注意人造的正确尺寸
- 填充物
- 边界
- 边际
faux.outerWidth();
问题
但有一个问题。我不知道当文本框中的文本被滚动(太长)并且插入符号不在文本的末尾,而是在文本框和插入符号之间时,如何处理这种情况。。。如果在末尾,则插入符号位置始终处于可能的最大位置(输入宽度减去右侧尺寸-填充、边框、边距)
我不确定是否有可能在文本框中获得文本滚动位置?如果可以的话,这个问题也可以解决。但我不知道有什么解决办法
希望这能有所帮助。这里有一个有效的例子
为了找到插入符号的位置,我对输入中的字母进行了计数,并将该值乘以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>
添加了一个隐藏容器,在其中插入输入值。之后,我得到容器的宽度并相应地移动DIV,那么canvas 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;
$('body').append('很抱歉,您的浏览器不支持HTML5画布元素');
var canvas=document.getElementById('textCanvas');
var ctx=canvas.getContext('2d');
ctx.measureText(文本);
var宽度=mes宽度;
我使用这种解决方案来获取一些文本的宽度,以便在WebGL中绘制它。我工作得很好,但我从未测试过当文本对于画布上下文来说太大时会发生什么,我认为它会很好,因为它是测量文本的API。但是何知道你应该彻底检查一下!:) 您可以使用
。这样,您就可以使用window.getSelection()
和getRangeAt
以及getclientracts
来获取位置。这应该适用于大多数现代浏览器,包括IE9+:
function getCaret() {
var caret = caret = {top: 0, height: 0},
sel = window.getSelection();
caret.top = 0;
caret.height = 0;
if(sel.rangeCount) {
var range = sel.getRangeAt(0);
var rects = range.getClientRects();
if (rects.length > 0) {
caret.top = rects[0].top;
caret.height = rects[0].height;
} else {
caret.top = range.startContainer.offsetTop - document.body.scrollTop;
caret.height = range.startContainer.clientHeight;
}
}
return caret;
}
(请记住,我所做的这个项目是针对Mobile Safari的,它使用了一个大型contenteditable视图。您可能需要调整它以满足您的需要。这更多是为了演示如何获取X和Y坐标。)
对于IE8及以下版本,IE有一个专有的API来获取相同的信息
棘手的部分是确保元素只允许纯文本。特别是粘贴事件。当span失去焦点(onblur)时,您希望将内容复制到隐藏字段中,以便发布。详细阐述我的上述评论,我想下面应该可以 为了显示原理,我省略了格式化,因此可能需要将元素(id=“spacer”)颜色设置为
#fffff e
,可能添加了一些前导空格像素等。。。但是卡雷特现在会按比例移动——只要id的测试和间隔使用相同的字体
当然,我们不知道[px]中的距离,但是我们能够定位内容(本例中为carret)与比例字体的宽度完全一致,因此如果这是最终目标(如OP第3行所述),那么。。。。瞧
<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>
函数调整()
{
document.getElementById('spacer').innerHTML=document.getElementById('test').value;
}
测试
^这里
更新:
<span id="spacer" style="color: #FFFFFF"></span>
这将使间隔符在白色背景上不可见,但不会阻止用户通过选择跨度元素高亮显示间隔符文本。保留使间隔棒不可选择的任务-有一个很好的解决方案类似的问题涵盖了您的问题:
<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>