446

これについては、私が試した別のスレッドがありました。ただし、問題が1つありtextareaます。コンテンツを削除しても、が縮小しないということです。正しいサイズに縮小する方法が見つかりません。値は、内容ではなく、clientHeightのフルサイズとして返されます。textarea

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

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if ( !text )
      return;

   var adjustedHeight = text.clientHeight;
   if ( !maxHeight || maxHeight > adjustedHeight )
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if ( maxHeight )
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if ( adjustedHeight > text.clientHeight )
         text.style.height = adjustedHeight + "px";
   }
}

window.onload = function() {
    document.getElementById("ta").onkeyup = function() {
      FitToContent( this, 500 )
    };
}
4

47 に答える 47

270

これは私にとってはうまくいきます(Firefox 3.6/4.0およびChrome 10/11):

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();
}
textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>

jsfiddleで試してみたい場合 は、1 行から始まり、必要な量だけ成長します。単一textareaの で問題ありませんが、そのような がたくさんあるようなものを書きたかったtextareaのです (通常、大きなテキスト ドキュメントに行が 1 つあるのと同じくらいです)。その場合、それは本当に遅いです。(Firefox では非常に遅いです。) だから、純粋な CSS を使用するアプローチが本当に必要です。これは で可能ですがcontenteditable、平文のみにしたいです。

于 2011-03-18T00:21:52.737 に答える
68

jQuery ソリューションは、要件に合わせて CSS を調整します

CSS...

div#container textarea {
    min-width: 270px;
    width: 270px;
    height: 22px;
    line-height: 24px;
    min-height: 22px;
    overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
    padding-top: 1.1em; /* fixes text jump on Enter keypress */
}

ジャバスクリプト...

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();

またはjQuery 1.7+の代替...

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();

実験の出発点として、絶対最小限のスタイリングでフィドルを作成しました... http://jsfiddle.net/53eAy/951/

于 2011-12-15T15:14:41.223 に答える
33
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Textarea autoresize</title>
    <style>
    textarea {
        overflow: hidden;
    }
    </style>
    <script>
    function resizeTextarea(ev) {
        this.style.height = '24px';
        this.style.height = this.scrollHeight + 12 + 'px';
    }

    var te = document.querySelector('textarea');
    te.addEventListener('input', resizeTextarea);
    </script>
</head>
<body>
    <textarea></textarea>
</body>
</html>

Firefox14およびChromium18でテスト済み。24と12の数字は任意です。テストして、最適なものを確認してください。

styleタグとscriptタグがなくても実行できますが、少し面倒になります(これは、古いスタイルのHTML + JSであり、推奨されていません)。

<textarea style="overflow: hidden" onkeyup="this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>

編集:最新のコード。onkeyup属性をaddEventListenerに変更しました。
編集:キーダウンはキーアップよりもうまく機能します編集:
使用する前に関数を宣言します
編集:入力はキーダウンよりもうまく機能します(thnx @ WASD42&@ MA-Maddin)

jsfiddle

于 2012-07-24T09:48:57.747 に答える
17

現在のclientHeightとコンテンツscrollHeightの高い方の値を使用しています。コンテンツを削除してscrollHeightを小さくすると、以前にstyle.heightで設定されたclientHeightが開いたままになっているため、計算された領域を小さくすることはできません。代わりに、scrollHeightのmax()と、textarea.rowsから事前定義または計算した最小の高さの値を取得できます。

一般に、フォームコントロールのscrollHeightに実際に依存するべきではありません。scrollHeightは、他のIE拡張機能よりも伝統的に広くサポートされていないことを除けば、HTML / CSSは、フォームコントロールが内部でどのように実装されるかについては何も述べておらず、scrollHeightが意味のあるものになるとは限りません。(従来、一部のブラウザーはタスクにOSウィジェットを使用しており、内部でのCSSとDOMの相互作用を不可能にしています。)少なくとも、エフェクトを有効にする前に、scrollHeight/clientHeightの存在をスニッフィングします。

より広く機能することが重要な場合に問題を回避するための別の可能な代替アプローチは、テキストエリアと同じ幅にサイズ設定され、同じフォントで設定された非表示のdivを使用することです。キーアップ時に、テキストをtextareaからhidden divのテキストノードにコピーします(「\ n」を改行に置き換え、innerHTMLを使用している場合は「<」/「&」を適切にエスケープすることを忘れないでください)。次に、divのoffsetHeightを測定するだけで、必要な高さが得られます。

于 2009-01-18T00:52:10.690 に答える
7

コンテンツ編集可能と考えた人はいますか? スクロールをいじる必要はありません。私が気に入っている唯一の JS は、ぼかしでデータを保存する予定がある場合です...そして、一般的なすべてのブラウザーと互換性があるようです: http://caniuse.com/#feat =コンテンツ編集可能

テキストボックスのようにスタイルを設定するだけで、サイズが自動調整されます...最小高さを優先テキスト高にしてください。

このアプローチの優れている点は、一部のブラウザーでタグを付けて保存できることです。

http://jsfiddle.net/gbutiri/v31o8xfo/

var _auto_value = '';
$(document).on('blur', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }

  // The text is here. Do whatever you want with it.
  $this.addClass('saving');

  if (_auto_value !== $this.html() || $this.hasClass('error')) {

    // below code is for example only.
    $.ajax({
      url: '/echo/json/?action=xyz_abc',
      data: 'data=' + $this.html(),
      type: 'post',
      datatype: 'json',
      success: function(d) {
        console.log(d);
        $this.removeClass('saving error').addClass('saved');
        var k = setTimeout(function() {
          $this.removeClass('saved error')
        }, 500);
      },
      error: function() {
        $this.removeClass('saving').addClass('error');
      }
    });
  } else {
    $this.removeClass('saving');
  }
}).on('focus mouseup', '.autosave', function() {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
  _auto_value = $this.html();
}).on('keyup', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
});
body {
  background: #3A3E3F;
  font-family: Arial;
}

label {
  font-size: 11px;
  color: #ddd;
}

.autoheight {
  min-height: 16px;
  font-size: 16px;
  margin: 0;
  padding: 10px;
  font-family: Arial;
  line-height: 20px;
  box-sizing: border-box;
  -o-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  overflow: hidden;
  display: block;
  resize: none;
  border: 0;
  outline: none;
  min-width: 200px;
  background: #ddd;
  max-height: 400px;
  overflow: auto;
}

.autoheight:hover {
  background: #eee;
}

.autoheight:focus {
  background: #fff;
}

.autosave {
  -webkit-transition: all .2s;
  -moz-transition: all .2s;
  transition: all .2s;
  position: relative;
  float: none;
}

.autoheight * {
  margin: 0;
  padding: 0;
}

.autosave.saving {
  background: #ff9;
}

.autosave.saved {
  background: #9f9;
}

.autosave.error {
  background: #f99;
}

.autosave:hover {
  background: #eee;
}

.autosave:focus {
  background: #fff;
}

[contenteditable=true]:empty:before {
  content: attr(placeholder);
  color: #999;
  position: relative;
  top: 0px;
  /*
    For IE only, do this:
    position: absolute;
    top: 10px;
    */
  cursor: text;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Your Name</label>
<div class="autoheight autosave contenteditable" contenteditable="true" placeholder="Your Name"></div>

于 2014-10-16T20:09:28.197 に答える
6

少し異なるアプローチがあります。

<div style="position: relative">
  <pre style="white-space: pre-wrap; word-wrap: break-word"></pre>
  <textarea style="position: absolute; top: 0; left: 0; width: 100%; height: 100%"></textarea>
</div>

textareaアイデアは、テキストを からにコピーし、preCSS にそれらが同じサイズであることを確認させることです。

利点は、フレームワークがイベントに触れることなくテキストを移動するためのシンプルなツールを提供することです。つまり、AngularJS では、 と に を追加しng-model="foo" ng-trim="false"ます。フィドルを参照してください。textareang-bind="foo + '\n'"pre

preのフォントサイズが と同じであることを確認してtextareaください。

于 2014-07-17T14:45:33.107 に答える
5

複数のテキストエリアに次のコードを使用しました。Chrome 12、Firefox 5、および IE 9 では、テキストエリアで削除、切り取り、貼り付けのアクションを実行しても問題なく動作します。

function attachAutoResizeEvents() {
  for (i = 1; i <= 4; i++) {
    var txtX = document.getElementById('txt' + i)
    var minH = txtX.style.height.substr(0, txtX.style.height.indexOf('px'))
    txtX.onchange = new Function("resize(this," + minH + ")")
    txtX.onkeyup = new Function("resize(this," + minH + ")")
    txtX.onchange(txtX, minH)
  }
}

function resize(txtX, minH) {
  txtX.style.height = 'auto' // required when delete, cut or paste is performed
  txtX.style.height = txtX.scrollHeight + 'px'
  if (txtX.scrollHeight <= minH)
    txtX.style.height = minH + 'px'
}
window.onload = attachAutoResizeEvents
textarea {
  border: 0 none;
  overflow: hidden;
  outline: none;
  background-color: #eee
}
<textarea style='height:100px;font-family:arial' id="txt1"></textarea>
<textarea style='height:125px;font-family:arial' id="txt2"></textarea>
<textarea style='height:150px;font-family:arial' id="txt3"></textarea>
<textarea style='height:175px;font-family:arial' id="txt4"></textarea>

于 2011-06-23T15:10:50.767 に答える
4

ビット修正。Operaで完璧に動作します

  $('textarea').bind('keyup keypress', function() {
      $(this).height('');
      var brCount = this.value.split('\n').length;
      this.rows = brCount+1; //++ To remove twitching
      var areaH = this.scrollHeight,
          lineHeight = $(this).css('line-height').replace('px',''),
          calcRows = Math.floor(areaH/lineHeight);
      this.rows = calcRows;
  });
于 2011-06-19T12:14:03.347 に答える
3

これをjqueryで実装する短くて正しい方法を知っています。余分な隠しdivは必要なく、ほとんどのブラウザで動作します

<script type="text/javascript">$(function(){
$("textarea").live("keyup keydown",function(){
var h=$(this);
h.height(60).height(h[0].scrollHeight);//where 60 is minimum height of textarea
});});

</script>
于 2012-05-24T08:46:12.153 に答える
3

さらにシンプルでクリーンなアプローチは次のとおりです。

// adjust height of textarea.auto-height
$(document).on( 'keyup', 'textarea.auto-height', function (e){
    $(this).css('height', 'auto' ); // you can have this here or declared in CSS instead
    $(this).height( this.scrollHeight );
}).keyup();

// および CSS

textarea.auto-height {
    resize: vertical;
    max-height: 600px; /* set as you need it */
    height: auto;      /* can be set here of in JS */
    overflow-y: auto;
    word-wrap:break-word
}

必要なのは、対象にしたい.auto-heightクラスにクラスを追加することだけです。textarea

FF、Chrome、Safari でテスト済み。何らかの理由でこれがうまくいかない場合はお知らせください。しかし、これは私がこれを機能させることがわかった最もクリーンで簡単な方法です。そして、それはうまくいきます!:D

于 2014-07-31T20:58:47.517 に答える
1

scrollHeight が信頼できる場合、次のようになります。

textarea.onkeyup=function() {
  this.style.height='';
  this.rows=this.value.split('\n').length;
  this.style.height=this.scrollHeight+'px';
}
于 2010-10-01T23:34:18.743 に答える
0

Angular 2+の場合、これを行うだけです

<textarea (keydown)="resize($event)"></textarea>


resize(e) {
    setTimeout(() => {
      e.target.style.height = 'auto';
      e.target.style.height = (e.target.scrollHeight)+'px';
    }, 0);
  }

textarea {
  resize: none;
  overflow: hidden;
}
于 2020-10-06T14:18:02.990 に答える
0

jQuery の解決策は、テキストエリアの高さを「auto」に設定し、scrollHeight を確認してから、テキストエリアが変更されるたびに ( JSFiddle )、テキストエリアの高さをそれに合わせることです。

$('textarea').on( 'input', function(){
    $(this).height( 'auto' ).height( this.scrollHeight );
});

テキストエリアを (AJAX などを介して) 動的に追加する場合は、これを $(document).ready に追加して、クラス 'autoheight' を持つすべてのテキストエリアがコンテンツと同じ高さに保たれるようにすることができます。

$(document).on( 'input', 'textarea.autoheight', function() {
    $(this).height( 'auto' ).height( this.scrollHeight );
});

Chrome、Firefox、Opera、IE でテストされ、動作しています。カット&ペースト、長文などにも対応。

于 2016-07-02T10:15:28.773 に答える
0

Firefox でちらつきがなく、メソッド withclientHeight... よりも高速なネイティブ Javascript ソリューション

div.textarea1) を含むすべてのセレクターにセレクターを追加しますtextarea。追加することを忘れないでくださいbox-sizing: border-box;

2) 次のスクリプトを含めます。

function resizeAll()
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      resize(textarea[i]);
}

function resize(textarea)
{
   var div = document.createElement("div");
   div.setAttribute("class","textarea");
   div.innerText=textarea.value+"\r\n";
   div.setAttribute("style","width:"+textarea.offsetWidth+'px;display:block;height:auto;left:0px;top:0px;position:fixed;z-index:-200;visibility:hidden;word-wrap:break-word;overflow:hidden;');
   textarea.form.appendChild(div);
   var h=div.offsetHeight;
   div.parentNode.removeChild(div);
   textarea.style.height=h+'px';
}

function resizeOnInput(e)
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      textarea[i].addEventListener("input",function(e){resize(e.target); return false;},false);
}

window.addEventListener("resize",function(){resizeAll();}, false);
window.addEventListener("load",function(){resizeAll();}, false);
resizeOnInput();

IE11、Firefox、Chrome でテスト済み。

このソリューションは、内部テキストを含むテキストエリアに似た div を作成し、高さを測定します。

于 2017-11-18T05:49:56.627 に答える
0

私が見つけた最良の方法:

$("textarea.auto-grow").each( function(){
    $(this).keyup(function(){
        $(this).height( $(this)[0].scrollHeight - Number( $(this).css("font-size").replace("px", "") ) );
    });
});

他の方法には、フォントサイズのバグがあります。

だからこそこれが一番。

于 2019-01-17T17:47:24.973 に答える
-1

次のjQuery関数を使用して、IE9とChromeでTextAreaのサイズを設定できます。$(document).ready()関数で定義されたセレクターからtextareaオブジェクトにバインドします。

function autoResize(obj, size) {
    obj.keyup(function () {
        if ($(this).val().length > size-1) {
            $(this).val( function() {
                $(this).height(function() {
                    return this.scrollHeight + 13;
                });
                alert('The maximum comment length is '+size+' characters.');
                return $(this).val().substring(0, size-1);
            });
        }
        $(this).height(function() {
            if  ($(this).val() == '') {
                return 15;
            } else {
                $(this).height(15);
                return ($(this).attr('scrollHeight')-2);
            }
        });
    }).keyup();
}

$(document).ready()関数では、このページのすべてのtextarea呼び出しに対して次の呼び出しがあります。

$('textarea').each( function() {
        autoResize($(this), 250);
});

250テキスト領域の文字数制限はどこにありますか。これは、テキストサイズが許す限り大きくなります(文字数とフォントサイズに基づきます)。また、テキストエリアから文字を削除したり、ユーザーが最初に貼り付けたテキストが多すぎたりすると、テキストエリアが適切に縮小されます。

于 2012-05-09T21:57:49.503 に答える
-1

次のコードを使用できます。

コフェスクリプト:

jQuery.fn.extend autoHeightTextarea: ->
  autoHeightTextarea_ = (element) ->
    jQuery(element).css(
      'height': 'auto'
      'overflow-y': 'hidden').height element.scrollHeight

  @each ->
    autoHeightTextarea_(@).on 'input', ->
      autoHeightTextarea_ @

$('textarea_class_or_id`').autoHeightTextarea()

Javascript

jQuery.fn.extend({
  autoHeightTextarea: function() {
    var autoHeightTextarea_;
    autoHeightTextarea_ = function(element) {
      return jQuery(element).css({
        'height': 'auto',
        'overflow-y': 'hidden'
      }).height(element.scrollHeight);
    };
    return this.each(function() {
      return autoHeightTextarea_(this).on('input', function() {
        return autoHeightTextarea_(this);
      });
    });
  }
});

$('textarea_class_or_id`').autoHeightTextarea();
于 2015-06-08T15:03:49.470 に答える
-1

一般的なブラウザでスクリプトをテストしましたが、Chrome と Safari では失敗しました。これは、常に更新可能な scrollHeight 変数のためです。

jQueryを使用してDisgruntledGoatスクリプトを適用し、クロム修正を追加しました

function fitToContent(/* JQuery */text, /* Number */maxHeight) {
    var adjustedHeight = text.height();
    var relative_error = parseInt(text.attr('relative_error'));
    if (!maxHeight || maxHeight > adjustedHeight) {
        adjustedHeight = Math.max(text[0].scrollHeight, adjustedHeight);
        if (maxHeight)
            adjustedHeight = Math.min(maxHeight, adjustedHeight);
        if ((adjustedHeight - relative_error) > text.height()) {
            text.css('height', (adjustedHeight - relative_error) + "px");
            // chrome fix
            if (text[0].scrollHeight != adjustedHeight) {
                var relative = text[0].scrollHeight - adjustedHeight;
                if (relative_error != relative) {
                    text.attr('relative_error', relative + relative_error);
                }
            }
        }
    }
}

function autoResizeText(/* Number */maxHeight) {
    var resize = function() {
        fitToContent($(this), maxHeight);
    };
    $("textarea").attr('relative_error', 0);
    $("textarea").each(resize);
    $("textarea").keyup(resize).keydown(resize);
}
于 2009-09-07T14:01:05.413 に答える
-1
$('textarea').bind('keyup change', function() {
    var $this = $(this), $offset = this.offsetHeight;
    $offset > $this.height() && $offset < 300 ?
        $this.css('height ', $offset)
            .attr('rows', $this.val().split('\n').length)
            .css({'height' : $this.attr('scrollHeight'),'overflow' : 'hidden'}) :
        $this.css('overflow','auto');
});
于 2011-02-17T10:14:52.190 に答える