您可以创建一个单独的(不可见)元素,并用从开始到光标位置的文本区域内容填充它。 Textarea 和“克隆”应该具有匹配的 CSS(字体属性、填充/边距/边框和宽度)。然后将这些元素堆叠在一起。
让我从一个工作示例开始,然后逐步浏览代码:http://jsfiddle.net/g7rBk/ http://jsfiddle.net/g7rBk/
更新了小提琴 http://jsfiddle.net/mLocgoeq/ (修复IE8)
HTML:
<textarea id="input"></textarea>
<div id="output"><span></span></div>
<div id="xy"></div>
文本区域是不言自明的。输出是一个隐藏元素,我们将向其传递文本内容并进行测量。重要的是我们将使用内联元素。 “xy”div 只是一个用于测试目的的指示器。
CSS:
/* identical styling to match the dimensions and position of textarea and its "clone"
*/
#input, #output {
position:absolute;
top:0;
left:0;
font:14px/1 monospace;
padding:5px;
border:1px solid #999;
white-space:pre;
margin:0;
background:transparent;
width:300px;
max-width:300px;
}
/* make sure the textarea isn't obscured by clone */
#input {
z-index:2;
min-height:200px;
}
#output {
border-color:transparent;
}
/* hide the span visually using opacity (not display:none), so it's still measurable; make it break long words inside like textarea does. */
#output span {
opacity:0;
word-wrap: break-word;
overflow-wrap: break-word;
}
/* the cursor position indicator */
#xy {
position:absolute;
width:4px;
height:4px;
background:#f00;
}
JavaScript:
/* get references to DOM nodes we'll use */
var input = document.getElementById('input'),
output = document.getElementById('output').firstChild,
position = document.getElementById('position'),
/* And finally, here it goes: */
update = function(){
/* Fill the clone with textarea content from start to the position of the caret. You may need to expand here to support older IE [1]. The replace /\n$/ is necessary to get position when cursor is at the beginning of empty new line.
*/
output.innerHTML = input.value.substr( 0, input.selectionStart ).replace(/\n$/,"\n\001");
/* the fun part!
We use an inline element, so getClientRects[2] will return a collection of rectangles wrapping each line of text.
We only need the position of the last rectangle.
*/
var rects = output.getClientRects(),
lastRect = rects[ rects.length - 1 ],
top = lastRect.top - input.scrollTop,
left = lastRect.left+lastRect.width;
/* position the little div and see if it matches caret position :) */
xy.style.cssText = "top: "+top+"px;left: "+left+"px";
}
[1] 文本区域中的插入符位置(从头开始的字符数) https://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
[2] https://developer.mozilla.org/en/docs/DOM/element.getClientRects https://developer.mozilla.org/en/docs/DOM/element.getClientRects
编辑:此示例仅适用于固定宽度的文本区域。要使其与用户可调整大小的文本区域一起使用,您需要向调整大小事件添加事件侦听器,并设置#output 尺寸以匹配新的#input 尺寸。