2008-12-04 14 views
8

J'essaie d'implémenter la saisie semi-automatique dans une zone de texte (similaire à http://www.pengoworks.com/workshop/jquery/autocomplete.htm). Ce que j'essaye de faire est quand un utilisateur entre un ensemble spécifique de caractères (par exemple insérer :) ils obtiendront un div AJAX rempli avec des allumettes sélectionnables possibles.Obtenir la position du curseur dans une zone de texte

Dans une zone de texte normale, cela est bien sûr simple, mais dans une zone de texte, je dois pouvoir faire apparaître la div à l'emplacement correct sur l'écran en fonction du curseur.

Quelqu'un peut-il fournir une direction?

Merci, -M

Répondre

4

Vous pouvez obtenir le caret en utilisant document.selection.createRange(), puis l'examiner pour révéler toutes les informations dont vous avez besoin (comme la position). Voir thoseexamples pour plus de détails.

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

Ce serait faire ... :)

0

une solution laide:

pour savoir: l'utilisation document.selection ...

pour ff: utiliser un pré derrière textarea , collez du texte avant le curseur, placez un marqueur html après (cursorPos) et obtenez la position du curseur via cet élément marqueur

Notes: | le code est moche, désolé pour ça | les polices pre et textarea doivent être identiques | l'opacité est utilisée pour la visualisation | il n'y a pas saisie semi-automatique, juste un curseur suivant div ici (comme vous tapez dans textarea) (modifier en fonction de votre besoin)

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