Getting cursor position in a Textarea

China☆狼群 提交于 2019-12-03 03:13:46

You can get the caret using document.selection.createRange(), and then examining it to reveal all the information you need (such as position). See those examples for more details.

Implementing an autocomplete in a text area is not that easy. I implemented a jquery plugin that does that, and i had to create a clone of the texarea to guess where the cursor is positioned inside the textarea. Its working, but its not perfect.

You can check it out here: http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/

I hope it helps.

Popara
    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];
}

That would do it ... :)

an ugly solution:

for ie: use document.selection...

for ff: use a pre behind textarea, paste text before cursor into it, put a marker html element after it (cursorPos), and get the cursor position via that marker element

Notes: | code is ugly, sorry for that | pre and textarea font must be the same | opacity is utilized for visualization | there is no autocomplete, just a cursor following div here (as you type inside textarea) (modify it based on your need)

<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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!