制作記事 Web制作マークアップJavaScripttextareaをテキスト量に合わせて高さを自動調整する

textareaをテキスト量に合わせて高さを自動調整する

過去に自作したことがあったが、盛大にバグってたので作り直し。ググったらすぐに参考になる記事が見つかった。その記事自体も2014年というかなり前に書かれていて驚き。前作は同時期に書いたようだけど、当時にこの記事を見つけたかったな、なんて思ったり。当時はとくにAndroid/iPhoneで挙動がトリッキーだったな、と苦い思い出。とりあえず、ChromeとiOSで動けばOKということで進めているので、違う環境で正常に動くは未検証。

HTML
<textarea class="js-sample"></textarea>
要素を指定する際、とりあえず「js-sample」というクラス名にしているが、実際はなんでもOK。
JavaScript(jQueryバージョン)
前提: jQueryをあらかじめ読み込んでいること
/**
 * textareaの高さを自動調整
 *
 * @param (object) tgt* 必須(なしの場合はエラー)textareaタグの指定 e.g. $('.js-textarea')
 * @param (number) font_size テキストエリア内のフォントサイズ
 * @param (number) line_height テキストエリア内の行間
 */
const autoAdjustTextareaHeight = (
  tgt, 
  font_size = 16,
  line_height = 1.6
) => {
  let h = Math.floor(font_size*line_height);

  tgt.css({
    'height': h,
    'padding': 0,
    'line-height': h + 'px',
    'font-size': font_size + 'px'
  }).on("input", function (e) {

    let _this = $(this),
        h_scroll = e.target.scrollHeight;

    if (h_scroll > e.target.offsetHeight) {  
      _this.height(h_scroll);
    } else {

      while (true) {
        _this.height(_this.height() - h); 
        if (e.target.scrollHeight > e.target.offsetHeight) {
          _this.height(e.target.scrollHeight);
          break;
        }
      }
    }
  });

  // すでにテキストエリアに文字列がある場合に備える
  tgt.height(tgt.get(0).scrollHeight);
}
autoAdjustTextareaHeight($('.js-sample'));

指定するテキストエリア内のフォントサイズや行間を指定する場合、第二引数と第三引数を使う。
例) フォントサイズを15px、行間を20pxにする場合

autoAdjustTextareaHeight($('.js-sample', 12, 20));