How to stop window jumping when typing in autoresizing textarea

后端 未结 4 1770
一整个雨季
一整个雨季 2020-12-21 06:35

I am using the accepted answer to this question to build a textarea that expands vertically as text overflows:





        
相关标签:
4条回答
  • 2020-12-21 07:01

    you should scroll the page to: scroll bar position + (textarea height after resize - textarea height before resize)

    here is the code:

        function resize () {
          var scrollLeft = window.pageXOffset ||
          (document.documentElement || document.body.parentNode || document.body).scrollLeft;
    
          var scrollTop  = window.pageYOffset ||
          (document.documentElement || document.body.parentNode || document.body).scrollTop;
    
          var prevHeight = text.style.height.slice(0, -2);
          text.style.height = "auto";
          var nextHeight = text.scrollHeight;
          text.style.height = text.scrollHeight + 'px';
          window.scrollTo(scrollLeft, scrollTop + (nextHeight - prevHeight));
        }
    

    OR you can do this using jquery (based on this answer):

        $('body').on('keyup', 'textarea', function (e) {
          var scrollTop  = $(document).scrollTop();
          var prevHeight = $(this).height();
          $(this).css('height', 'auto');
          var nextHeight = this.scrollHeight;
          $(this).height(nextHeight);
          $(document).scrollTop(scrollTop + (nextHeight - prevHeight));
        });
        $( 'textarea' ).keyup();
    
    0 讨论(0)
  • 2020-12-21 07:01

    A way to do the accepted answer when the textarea is in a scrollable div:

    function getScrollParent(node) {
        if (node == null) {
            return null;
        }
    
        if (node.scrollHeight > node.clientHeight) {
            return node;
        } else {
            return getScrollParent(node.parentNode);
        }
    }
    
    function resize(){
        // 'this' is the textarea
        const scrollParent = getScrollParent(this);
        const scrollTop = scrollParent ? scrollParent.scrollTop : null;
        const scrollLeft = scrollParent ? scrollParent.scrollLeft : null;
    
        this.style.height = "auto";
        this.style.height = this.scrollHeight + "px";
    
        if (scrollParent) {
            scrollParent.scrollTo(scrollLeft, scrollTop);
        }
    };
    
    0 讨论(0)
  • 2020-12-21 07:13

    Save the scrollLeft, scrollTop values, and then restore them after resizing the textarea:

    function resize () {
       var scrollLeft = window.pageXOffset ||
       (document.documentElement || document.body.parentNode || document.body).scrollLeft;
    
       var scrollTop  = window.pageYOffset ||
       (document.documentElement || document.body.parentNode || document.body).scrollTop;
    
       text.style.height = "auto";
       text.style.height = text.scrollHeight + 'px';
    
       window.scrollTo(scrollLeft, scrollTop);
    }
    

    JSFiddle: http://jsfiddle.net/losnir/nnkeH/1

    0 讨论(0)
  • 2020-12-21 07:23

    My response is based on the fiddle in the accepted answer for: height of textarea increases when value increased but does not reduce when value is decreased.

    This works on page load and when the text is altered in any way (cut, paste, typing, etc.)

    $('textarea').on('keyup keydown', function () {
    var $this = $(this);
    var initialHeight = $this.height();
    
    $this
        .height(initialHeight - 40)
        .height($this[0].scrollHeight + 20);}).trigger('keyup');
    

    The reason I grab the initial height is so that the textarea doesn't have to jump to 1 or any other static number to trigger a value for scrollHeight. (it's my understanding that is what causes the screen to change scrolling because the textbox is set to that static height (usually 1) and then expands) The reason that I add 20 to scrollHeight is because sometimes scrollHeight is off by 1 or 2px and the text looks bunched up at the bottom. So to give it more space I personally add 20.

    0 讨论(0)
提交回复
热议问题