View Full Version : Position of curser in textarea in pixels

08-14-2006, 06:42 PM

I need to know how to retrieve the position of a curser in a textarea in pixels. I want to position a div tag right under the curser as people are typing in a text box.

I can do it in IE this way

document.getElementById('mytextarea').onkeyup = function (){
testRange = document.selection.createRange();
s = document.getElementById('box');
s.style.position = 'absolute';
s.style.left = testRange.offsetLeft;
s.style.top = testRange.offsetTop;

where the html would be <textarea id="mytextarea"></textarea> and
<div id="box"></box>.

the offsetleft property in IE gives me the pixels where the curser is. I need an equivilent in Firefox but I have no idea how to do it. If anyone can help i would appreciate it.


08-14-2006, 09:18 PM
You might investigate the properties of the window.getSelection() object, though barring that, I'm not entirely sure that Firefox provides an interface to get at that information directly.

08-15-2006, 12:08 AM
I have investigated document.getSelection() but that doesn't do what I want it to. The thing is that I want to know the position of the curser in a text area. not put what is selected on the webpage into a text area. I investigated the dom range object but it doesn't seem to have a method that tells what the pixel location of the selection is.


Thanks for the help.

08-15-2006, 04:32 AM
To do that in Firefox you would need a lot more code.

You would need to copy all of the text in the textarea and put it into a hidden <span> that has the font-family and width set to that of the textarea, then using the selectionStart and selectionEnd properties of the textarea (Firefox, NS7.1+, Moz1.3+, and Opera 8+) figure out where the cursor would be, then remove the text after that point then grab the height, then figure out how many lines of text there are, remove all of the previous lines, set the width to auto and find the width. Just keep in mind that it would probably not be as accurate as IE/Win's method.

08-16-2006, 09:48 PM

i see where I have to go now. It doesn't have to be too accurate. Maybe I can get something some what accrurate. If I do I will post it.


08-22-2006, 08:50 PM
I wrote a little script that ended up not working. It is pretty accurate but when there was a long string that wrapped it would slow down the browser a lot. I also found that there was no way to know if they had scrolled. As soon as the text is longer than the box you are pretty much hosed. Or at least I can't think of a good thing to do. Well Here is the code if anyone wants to take a look.


var letterWidthArray = new Array();

var possibleCharString = new String('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%$%^&*()-_=+~`,.?><;:][{}|"');
possibleCharString += "'";
var spaceChar = String.fromCharCode(32);

var currentLocationArray = new Array();
currentLocationArray['x'] = 0;
currentLocationArray['y'] = 0;

possibleCharString += spaceChar;
var ta;

function curserLocation(textArea){
ta = textArea;
textArea.onkeyup = function (){

function findCurserLocation(textArea){

var textAreaLocation = getTextAreaXY(textArea);
var theValue = textArea.value;
var sPos = textArea.selectionStart;
var theStr = theValue.substring(0, sPos);
theStrArray = new Array();

theStrArray = theStr.split("\n");

lastStr = theStrArray[theStrArray.length-1];

begStringWidth = getXPosOfCurser(lastStr);

var textAreaXY = new Array();
textAreaXY = getTextAreaXY(textArea);

CursorX = textAreaXY[0] + begStringWidth;

CursorY = textAreaXY[1] + (fontHeight * findNumOfRows(theStrArray, textArea));

//take out later just for testing purposes.
document.getElementById('box').style.display = 'block';
document.getElementById('box').style.position = 'absolute';
document.getElementById('box').style.left = CursorX + 'px';
document.getElementById('box').style.top = CursorY + 'px';


function findNumOfRows(strArray, textArea){
var taWidth = getTextAreaWidth(textArea);
var totalRows = -1;
for(z = 0; z < strArray.length; z++){
var w = getStrWidth(strArray[z]);
if(taWidth < w){
totalRows += Math.floor(w/taWidth);
return totalRows;

function getStrWidth(str){
theWidth = 0;
for(a= 0; a < str.length; a++){
index = getLocationInPossibleString(str.charAt(a));
theWidth = letterWidthArray[index] + theWidth;
return theWidth;

function getXPosOfCurser(str){

var offSet = getWrapOffSetStr(str);
//var strWidth = getStrWidth(offSet);

return offSet;//strWidth;

function getWrapOffSetStr(s){
var taWidth = getTextAreaWidth(ta);
var sWidth = getStrWidth(s);
if(theWidth >= taWidth){
temp = Math.floor(theWidth/taWidth);
temp = temp*taWidth
return theWidth - temp;
return sWidth;
/* works but is really slow
function getWrapOffSetStr(s){
var taWidth = getTextAreaWidth(ta);
var theWidth = 0;
var begLineIndex = 0;

for(ilb= 0; ilb < s.length; ilb++){
index = getLocationInPossibleString(s.charAt(ilb));
theWidth = letterWidthArray[index] + theWidth;
if(theWidth >= taWidth){
var newStr = s.substr(begLineIndex,ilb);
var regex = /([\S]+)$/;//finds the last word of the string
begLineIndex = newStr.search(regex);
theWidth = 0;
var offsetString = s.substr(begLineIndex, s.length);
return offsetString;

function getCharWidth(char){
index = getLocationInPossibleString(char);
return letterWidthArray[index];

function getLocationInPossibleString(char){
pos = possibleCharString.indexOf(char);
if(pos != -1){
return pos;
return false;

function getTextAreaWidth(textArea){
var taW = textArea.offsetWidth;
return taW;

function getWindowSize() {
windowSize = new Array();
windowSize[0] = document.body.clientWidth;
windowSize[1] = document.body.clientHeight;
return windowSize;


function getTextAreaXY(textArea){
var TAPosition = new Array();
TAPosition[0] = textArea.offsetLeft;
TAPosition[1] = textArea.offsetTop;
return TAPosition;

function initFontWidth(){
for(i=0 ; i<possibleCharString.length ; i++){
document.getElementById('charWidth').innerHTML = possibleCharString.charAt(i);
if(possibleCharString.charAt(i) != ' '){
letterWidthArray[i] = document.getElementById('charWidth').offsetWidth;
letterWidthArray[i] = getSpaceWidth();

function getSpaceWidth(){
document.getElementById('charWidth').innerHTML = possibleCharString.charAt(3) + ' ' + possibleCharString.charAt(3);
spaceWidth = document.getElementById('charWidth').offsetWidth - (2 * letterWidthArray[0]);
return spaceWidth;

var fontHeight = 0;
function initFontHeight(){
fontHeight = document.getElementById('charWidth').offsetHeight;

08-22-2006, 09:11 PM
I'm not sure why the scrolling matters, but I think you could use scrollTop and scrollLeft to check for it.

08-22-2006, 10:04 PM
It matters because I was counting the lines of text in the textarea. and I multiply the number of lines by the hieght of the font and that gives me the top pixel value. When the text is longer than the textarea then my estimation of lines is larger than the lines that are showing. It is even worse if they scroll a little and then put the curser in the middle of the textarea.

Does scrolltop give how many lines rows have been scrolled?

08-22-2006, 10:09 PM
I see, scrollTop returns the pixels that have been scrolled down. That would fix that problem. nice. hmm

08-28-2006, 08:36 AM
Thanks MikoLone very much, your code is things that I am looking, It hepl me much.

Thanks a lot