8 Stimmen

Cursorposition in einer Textarea ermitteln

Ich versuche, Autocomplete in einem Textbereich zu implementieren (ähnlich wie bei http://www.pengoworks.com/workshop/jquery/autocomplete.htm ).

Was ich versuche zu tun ist, wenn ein Benutzer einen bestimmten Satz von Zeichen (sagen Sie einfügen:) Sie erhalten eine AJAX gefüllt div mit möglichen auswählbaren Übereinstimmungen.

In einem normalen Textfeld ist dies natürlich einfach, aber in einem Textbereich muss ich in der Lage sein, das Div an der richtigen Stelle auf dem Bildschirm basierend auf dem Cursor zu öffnen.

Kann mir jemand einen Hinweis geben?

Danke! -M

4voto

Eran Galperin Punkte 84916

Sie können die Einfügemarke mit document.selection.createRange() abrufen und sie dann untersuchen, um alle benötigten Informationen (z. B. die Position) zu ermitteln. Siehe die Beispiele für weitere Einzelheiten.

1voto

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

Das würde genügen ... :)

1voto

Amir Punkte 1149

Eine Autovervollständigung in einem Textbereich zu implementieren ist nicht so einfach. Ich habe ein Jquery-Plugin implementiert, das das tut, und ich musste einen Klon des Textbereichs erstellen, um zu erraten, wo der Cursor im Textbereich positioniert ist. Es funktioniert, aber es ist nicht perfekt.

Sie können es hier nachlesen: http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/

Ich hoffe, es hilft.

0voto

Eine hässliche Lösung:

z. B.: document.selection verwenden...

für ff: verwenden Sie ein Textarea vor dem Cursor, fügen Sie Text vor dem Cursor ein, fügen Sie ein Marker-HTML-Element dahinter ein (cursorPos), und ermitteln Sie die Cursorposition über dieses Markerelement

Anmerkungen: | Code ist hässlich, sorry dafür | pre und Textarea Schriftart muss die gleiche sein | Opazität ist für die Visualisierung verwendet | es gibt keine Autovervollständigung, nur ein Cursor nach div hier (wie Sie innerhalb Textarea geben) (ändern Sie es auf Ihre Bedürfnisse)

<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>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X