1

I have an auto-expanding textarea. When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump. This happens when trying to type at the bottom, because the document height is also growing.

Ideas, anyone?

Codepen: https://codepen.io/btn-ninja/pen/bRVKYe

function growTextarea (i,elem) {
    var elem = $(elem);
    var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
     var resizeTextarea = function( elem ) {
        elem.css('height', 'auto').css('height', elem.prop('scrollHeight') + offset );            
    };
    elem.on('input', function() {
        resizeTextarea( $(this) );
    });
    resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);
Jen
  • 1,663
  • 1
  • 17
  • 34
  • What exactly do you mean by 'jump'? Do you mean the slight page shift as the scrollbar loads in? – Jack Parkinson Jun 08 '17 at 11:08
  • 1
    Are you in IE ? – Kashkain Jun 08 '17 at 11:10
  • You are changing the height on every input which is causing the flicker. Did you check this library out? http://www.technoreply.com/autogrow-textarea-plugin-3-0/ – Vishwas Singh Chouhan Jun 08 '17 at 11:26
  • The jump is vertical, when you add/paste very long content to the textarea. TO emphasize it, I added a 200px bottom margin on the textarea. Then you see, as the page content grows, there is vertical-scrollbar-jumping in the bottom of the page. (PS - The suggested plugin is much longer code and doesn't address this issue.) – Jen Jun 08 '17 at 11:49

2 Answers2

2

This is better than my last attempt, even though I got the solution here :). This is basically storing the scroll position before the resize and then reapplying those values to the scroll position after the textarea is resized.

On an unrelated note. I have also removed the + offset on the height change jQuery, because it kept on adding unneeded additional height to the textarea. Doing this added a scroll bar on the textarea, so I set the textarea to overflow:hidden in the CSS.

https://codepen.io/anon/pen/QgjVWY

function growTextarea (i,elem) {
        var elem = $(elem);
        var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
        var resizeTextarea = function( elem ) {
          // two additional variables getting the top and left scoll positions.
          var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft;
          var scrollTop  = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;
          elem.css('height', 'auto').css('height', elem.prop('scrollHeight') );
          // Applying previous top and left scroll position after textarea resize. 
          window.scrollTo(scrollLeft, scrollTop);
        };
        elem.on('input', function() {
          resizeTextarea( $(this) );
        });
        resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);
.jTextarea {
  overflow:hidden;
}
<form style="width:500px; margin:20px auto;">
  <small>Known issue: When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.</small><br>
  <textarea rows="1" class="jTextarea"></textarea>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
WizardCoder
  • 3,353
  • 9
  • 20
0

You could use $(window).scrollTop(elem.prop('scrollHeight')); to force the window to scroll to the bottom of the element.

function growTextarea (i,elem) {
  var elem = $(elem);
  var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
   var resizeTextarea = function( elem ) {
     elem.css('height', 'auto').css('height', elem.prop('scrollHeight') + offset );   
     $(window).scrollTop(elem.prop('scrollHeight'));
  };
  elem.on('input', function() {
      resizeTextarea( $(this) ); 
  });
  resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);
<form style="width:500px; margin:20px auto;">
  <small>Known issue: When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.</small><br>
  <textarea rows="1" class="jTextarea"></textarea>
</form>
WizardCoder
  • 3,353
  • 9
  • 20
  • Wouldn't this solution need to depend on the position of the text cursor (and further complicated because that's not necessarily the mouse cursor)? I mean , you don't want to do this if they're in the middle of the long textarea. – Jen Jun 08 '17 at 11:40
  • Yeah I realise now it is a dum solution :P – WizardCoder Jun 08 '17 at 11:47
  • lol, I am sure there is a clever solution, but I don't know it. :) – Jen Jun 08 '17 at 11:50