How to stop window jumping when typing in autoresizing textarea

跟風遠走 提交于 2019-12-01 21:59:08

问题


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

<!DOCTYPE html>
<html>
<head>
<title>autoresizing textarea</title>
<style type="text/css">
textarea {
 border: 0 none white;
 overflow: hidden;
 padding: 0;
 outline: none;
 background-color: #D0D0D0;
 resize: none;
}
</style>
<script type="text/javascript">
var observe;
if (window.attachEvent) {
 observe = function (element, event, handler) {
  element.attachEvent('on'+event, handler);
 };
}
else {
 observe = function (element, event, handler) {
  element.addEventListener(event, handler, false);
 };
}
function init () {
 var text = document.getElementById('text');
 function resize () {
  text.style.height = 'auto';
  text.style.height = text.scrollHeight+'px';
 }
 /* 0-timeout to get the already changed text */
 function delayedResize () {
  window.setTimeout(resize, 0);
 }
 observe(text, 'change',  resize);
 observe(text, 'cut',     delayedResize);
 observe(text, 'paste',   delayedResize);
 observe(text, 'drop',    delayedResize);
 observe(text, 'keydown', delayedResize);

 text.focus();
 text.select();
 resize();
}
</script>
</head>
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>
</html>

It works well until the size of the textarea grows longer than the browser window. At that point the top of the window jumps to the top of the textarea every time a key is pressed. Can you help me understand why and how to fix it?

An ideal fix would be to keep the page from moving at all. But if it's easier to keep the bottom of the page tied to the bottom of the textarea, that would work too.

I am having this issue in Firefox 21.0 and Chrome 28.0: http://jsfiddle.net/CbqFv/


回答1:


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




回答2:


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();



回答3:


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);
    }
};


来源:https://stackoverflow.com/questions/18262729/how-to-stop-window-jumping-when-typing-in-autoresizing-textarea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!