6

この質問に対する受け入れられた回答を使用して、テキストがオーバーフローすると垂直方向に拡大するテキストエリアを構築しています。

<!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>

テキストエリアのサイズがブラウザ ウィンドウよりも長くなるまでは、うまく機能します。その時点で、キーが押されるたびに、ウィンドウの上部がテキストエリアの上部にジャンプします。その理由と修正方法を理解するのを手伝ってもらえますか?

理想的な修正は、ページがまったく動かないようにすることです。しかし、ページの下部をテキストエリアの下部に結び付けておく方が簡単であれば、それも機能します。

Firefox 21.0 と Chrome 28.0 でこの問題が発生しています: http://jsfiddle.net/CbqFv/

4

6 に答える 6

1

ページをスクロールする必要があります: スクロール バーの位置 + (サイズ変更後のテキスト領域の高さ - サイズ変更前のテキスト領域の高さ)

コードは次のとおりです。

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

または、jquery を使用してこれを行うことができます (この回答に基づく):

    $('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();
于 2014-03-30T04:06:57.823 に答える
1

Adam Beres-Deak と @losnir のコードを組み合わせて、これがこれまでのところ最良の解決策であることがわかり、以下の結果が得られました。

群を抜いて最も有用なもの:

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 textAreas = [].slice.call(document.querySelectorAll('textarea[data-adaptheight]'));
    textAreas.forEach(function(el){
        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;
            el.style.resize = "none";
            el.style.overflow = 'hidden';
            el.style.boxSizing = el.style.mozBoxSizing = 'border-box';
            el.style.height = "auto";
            el.style.height = el.scrollHeight + 'px';
            window.scrollTo(scrollLeft, scrollTop);
        }
        observe(el, 'input', resize);
        resize();
    });
}
init();
<textarea data-adaptheight style="padding: 7px;width: 100%;display: block;" rows="1" cols="40" placeholder="Your input">
</textarea>

于 2021-02-05T21:02:57.037 に答える