5

I have an expanding textarea. When the textarea has already expanded enough to reach the bottom of the window, the body flickers/scrolls back to the top of the textarea and you cannot see the last characters you've keyed in unless you scroll the window.

The sample can be found in this jsfiddle. I tried adding a scrollTo to the body

window.scrollTo(0, document.getElementsByTagName('textarea')[0].getBoundingClientRect().bottom);

How can I calculate the offset of the cursor in textarea from the window? I was thinking of getting the top offset of the cursor and just scrolling the window to its position if the cursor is already beyond the fold.

Help on this would be greatly appreciated :)

Krish R
  • 22,583
  • 7
  • 50
  • 59
dork
  • 4,396
  • 2
  • 28
  • 56
  • I think it's doing that flickering thing because I replace the value of the textarea – dork Nov 22 '13 at 07:14
  • Another thing I noticed is that it focuses correctly when I hit the backspace button – dork Dec 16 '13 at 07:32
  • oh, i think it's because the backspace button doesn't trigger the keypress event, which in turn doesn't call the resize function of the textarea. how can i duplicate that effect to avoid the flickering when characters are typed in? – dork Dec 16 '13 at 08:00
  • Why are you setting the caret position in the first place? Why are you not just setting the height? Wondering what I am missing... – epascarello Dec 16 '13 at 15:12
  • What's wrong with the scrollTo that you tried? It seems to work in Firefox and Chrome – apaul Dec 16 '13 at 20:03
  • @epascarello because i'm replacing the value of the textarea. if you replace the value of the textarea, the caret would go to the start/end of the text. if i typed something in the middle of the text, i would want the caret to be in front of the character i typed. – dork Dec 17 '13 at 04:14
  • @apaul34208 it works fine if i'm just typing continuously. but if i type something in the middle of the textarea, the window scrolls to the bottom of the textarea. it should only scroll to where i'm typing – dork Dec 17 '13 at 04:17

3 Answers3

0

I use the following for ALL mouse position issues and have never had a problem. I don't see why it wouldn't work for this instance aswell.

var cX;
var cY;
document.onmousemove = function(e){
    cX = e.pageX;
    cY = e.pageY;
}

You could use it like I have:

window.scrollTo(0, cX);

Or simply put the e.pageX into your code example. cX, cY are cursor coordinates.

StorySystems
  • 167
  • 9
0

your code is great - i just added some milliseconds of timeout (around 100-200 is enough) and now it behaves nicely. Just wondered what that on('focus') event handler is for. And guess you can skip calling focus() in resize() function...

Kjell
  • 832
  • 7
  • 11
  • but it's focusing at the end of the textarea when you type in the middle part of it – dork Dec 19 '13 at 04:33
  • hm, i see the problem. Guess you have to calculate the approximate position of the carret in the textarea and adjust your scrolling by that... – Kjell Dec 19 '13 at 07:57
0

I found a solution right here in stack! https://stackoverflow.com/a/18262927/769326

I added the code snippet found there in the resize function also.

function resize(e){
var text = _this.value,
    lines = text.split('\n'),
    cursorPosition = $this.getCursorPosition(),
    scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft,
    scrollTop  = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;

    for(var i = 0, length = lines.length; i < length; i++){
        if(lines[i].length <= settings.charactersPerLine){
            continue;
        }

        var j = 0,
            space = settings.charactersPerLine;

        while(j++ <= settings.charactersPerLine){
            if(lines[i].charAt(j) === ' '){
                space = j;
            }
        }

        lines[i+1] = lines[i].substr(space) + (lines[i + 1] || '');
        lines[i] = lines[i].substr(0, space);
    }

    _this.value = lines.join('\n');

    if(cursorPosition == text.length){
        setCaretToPos(_this, cursorPosition + 1);
    }
    else{
        setCaretToPos(_this, cursorPosition);
    }

    _this.style.height = elementHeight;
    _this.style.height = _this.scrollHeight + 'px';
    _this.style.overflow = 'hidden';

    window.scrollTo(scrollLeft, scrollTop);
}

here's the jsfiddle

Community
  • 1
  • 1
dork
  • 4,396
  • 2
  • 28
  • 56