获取文本区域中的光标位置
Posted
技术标签:
【中文标题】获取文本区域中的光标位置【英文标题】:Getting cursor position in a Textarea 【发布时间】:2010-09-25 08:51:36 【问题描述】:我正在尝试在文本区域中实现自动完成(类似于http://www.pengoworks.com/workshop/jquery/autocomplete.htm)。
我想要做的是,当用户输入一组特定的字符(比如插入:)时,他们将获得一个 AJAX 填充的 div,其中包含可能的可选匹配项。
在常规文本框中,这当然很简单,但在文本区域中,我需要能够根据光标在屏幕上的正确位置弹出 div。
任何人都可以提供任何方向吗?
谢谢, -M
【问题讨论】:
【参考方案1】:您可以使用 document.selection.createRange() 获取插入符号,然后检查它以显示您需要的所有信息(例如位置)。详情请见thoseexamples。
【讨论】:
【参考方案2】:在文本区域中实现自动完成并不是那么容易。我实现了一个 jquery 插件,我必须创建一个 texarea 的克隆来猜测光标在 textarea 内的位置。 它的工作,但它并不完美。
您可以在这里查看:http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
希望对你有帮助。
【讨论】:
【参考方案3】: function getCursor(nBox)
var cursorPos = 0;
if (document.selection)
nBox.focus();
var tmpRange = document.selection.createRange();
tmpRange.moveStart('character',-nBox.value.length);
cursorPos = tmpRange.text.length;
else
if (nBox.selectionStart || nBox.selectionStart == '0')
cursorPos = nBox.selectionStart;
return cursorPos;
function detectLine(nBox,lines)
var cursorPos = getCursor(nBox);
var z = 0; //Sum of characters in lines
var lineNumber = 1;
for (var i=1; i<=lines.length; i++)
z = sumLines(i)+i; // +i because cursorPos is taking in account endcharacters of each line.
if (z >= cursorPos)
lineNumber = i;
break;
return lineNumber;
function sumLines(arrayLevel)
sumLine = 0;
for (var k=0; k<arrayLevel; k++)
sumLine += lines[k].length;
return sumLine;
function detectWord(lineString, area, currentLine, linijeKoda)
function sumWords(arrayLevel)
var sumLine = 0;
for (var k=0; k<arrayLevel; k++)
sumLine += words[k].length;
return sumLine;
var cursorPos = getCursor(area);
var sumOfPrevChars =0;
for (var i=1; i<currentLine; i++)
sumOfPrevChars += linijeKoda[i].length;
var cursorLinePos = cursorPos - sumOfPrevChars;
var words = lineString.split(" ");
var word;
var y = 0;
for(var i=1; i<=words.length; i++)
y = sumWords(i) + i;
if(y >= cursorLinePos)
word = i;
break;
return word;
var area = document.getElementById("area");
var linijeKoda = area.value.split("\n");
var currentLine = detectLine(area,linijeKoda);
var lineString = linijeKoda[currentLine-1];
var activeWord = detectWord(lineString, area, currentLine, linijeKoda);
var words = lineString.split(" ");
if(words.length > 1)
var possibleString = words[activeWord-1];
else
var possibleString = words[0];
这样就可以了... :)
【讨论】:
【参考方案4】:一个丑陋的解决方案:
即:使用 document.selection...
对于ff:在textarea后面使用pre,将光标前的文本粘贴到其中,在其后放置一个标记html元素(cursorPos),并通过该标记元素获取光标位置
注意事项:|代码很丑,抱歉| pre 和 textarea 字体必须相同 |不透明度用于可视化 |没有自动完成功能,这里只有一个光标跟随 div(当您在 textarea 中输入时)(根据您的需要进行修改)
<html>
<style>
pre.studentCodeColor
position:absolute;
margin:0;
padding:0;
border:1px solid blue;
z-index:2;
textarea.studentCode
position:relative;
margin:0;
padding:0;
border:1px solid silver;
z-index:3;
overflow:visible;
opacity:0.5;
filter:alpha(opacity=50);
</style>
hello world<br/>
how are you<br/>
<pre class="studentCodeColor" id="preBehindMyTextarea">
</pre>
<textarea id="myTextarea" class="studentCode" cols="100" rows="30" onkeyup="document.selection?ieTaKeyUp():taKeyUp();">
</textarea>
<div
style="width:100px;height:60px;position:absolute;border:1px solid red;background-color:yellow"
id="autoCompleteSelector">
autocomplete contents
</div>
<script>
var myTextarea = document.getElementById('myTextarea');
var preBehindMyTextarea = document.getElementById('preBehindMyTextarea');
var autoCompleteSelector = document.getElementById('autoCompleteSelector');
function ieTaKeyUp()
var r = document.selection.createRange();
autoCompleteSelector.style.top = r.offsetTop;
autoCompleteSelector.style.left = r.offsetLeft;
function taKeyUp()
taSelectionStart = myTextarea.selectionStart;
preBehindMyTextarea.innerHTML = myTextarea.value.substr(0,taSelectionStart)+'<span id="cursorPos">';
cp = document.getElementById('cursorPos');
leftTop = findPos(cp);
autoCompleteSelector.style.top = leftTop[1];
autoCompleteSelector.style.left = leftTop[0];
function findPos(obj)
var curleft = curtop = 0;
if (obj.offsetParent)
do
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
while (obj = obj.offsetParent);
return [curleft,curtop];
//myTextarea.selectionStart
</script>
</html>
【讨论】:
以上是关于获取文本区域中的光标位置的主要内容,如果未能解决你的问题,请参考以下文章