2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

jQueryでtextareaの高さを自動調節する

Last updated at Posted at 2020-07-12

テキストエリアの高さを行数に応じて自動調節する方法を調べた結果、最終的に超シンプルな方法に落ち着いたのでメモ。検索で引っかかるどれよりもどシンプルに仕上がっていると思います。

使っているもの

名前 ver
macOS Catalina 10.15.5
jQuery.min.js v3.4.1(googleapisからリンクで取得)

使う言語

  • javascript(というかjQuery)
  • html

まずは結論

htmlファイルのbody上部にこれさえ突っ込めばOKです。
必要に応じて呼び出し元の要素の指定をidやクラスに変更してください。

※v1.7以上のjQueryを別途読み込んでいる場合、一行目(src=とか書いてあるscriptタグ)は不要です。
※v1.7未満のjQueryを別途読み込んでいる場合、$(documend).onが使えません。
https://api.jquery.com/on/
v1.7未満のjQueryを使う場合は代わりにbindが使えそうですが、試していないので保証はできません。
https://www.aipacommander.com/entry/2015/09/17/192659

表示したいページのhtml.html
--前略 ヘッダとか諸々--
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
    $(document).on("change", "textarea", function(evt){
        var min_height = 40; //テキストエリアの最小の高さをお好みで設定
        $(evt.target).height(min_height); //一旦最小サイズにする
        $(evt.target).height(evt.target.scrollHeight); //スクロールなしでテキストが収まる最小の高さに上書き
    });
</script>

--後略 この下にテキストボックスなど--
html中で読み込んでおくCSS.css
textarea{
    resize: none;/*ユーザによるリサイズを不可にし、右下に///が出ないようにする*/
}

コード中の"textarea"部分がセレクタの指定箇所なので、"#id名"なり".class名"なり"textarea[name='テキストエリア名']"なり状況に応じたセレクタに変更しましょう。

答えにたどり着くまで

まずは「textarea 自動リサイズ」とか「textarea 高さ 調節」なんかで検索して調べました。

  1. 改行コードの数を取得する系
    改行コードを正規表現で抽出&その数に応じて幅を変えるというアプローチ。
    例: https://qiita.com/ampersand/items/ceaa5066d44990d30df3
    ただ、自動改行も取得できないと困るので目的に合わず。

  2. 親要素のサイズを自動変更し、それに追随させる
    例:https://qiita.com/tsmd/items/fce7bf1f65f03239eef0
    ちょっと複雑で設定ミスが怖いので見送り。

  3. textareaが持つscrollHeightの値を使う

    1. https://qiita.com/osamingo/items/3ee00333f6fcd33fa2a1
      scrollHeightを使い、テキストエリアから文字がはみ出していたら最適なサイズまで拡大。ただ、文字を減らしたときにリサイズしない。
    2. https://pisuke-code.com/jquery-make-textarea-auto-resize/
      while文を使ってちょっとずつ高さを減らし、スクロールが必要になったら表示可能な最小サイズにして終了、というアプローチ。

3-2が最も目的にあっていたのですが、whileを使っているのでミスって無限ループを発生させ、PCが唸りを上げること数回。
修正が怖くなったので、whileを使わずになんとかしようと思った結果、きづきました。
一度最小まで縮めて、はみ出てたら拡大すればいい。それだけのことでした。

理屈

  1. jQueryを使いたいので、googleapisからjQueryを読み込みます。
  2. テキストエリアの値が変更されたときに、jQueryの機能を使って検出します。
  3. 値が変更されたテキストエリアのサイズを、一旦min_heightに変更します。
  4. scrollHeightの値で高さを上書きします。

ちなみに、テキストエリアの幅が余っているときに3をスキップするとうまく行かないのは、以下が原因です。

要素のコンテンツが垂直スクロールバーを表示することなく収まる場合、その scrollHeight は clientHeight と等しくなります。
https://developer.mozilla.org/ja/docs/Web/API/Element/scrollHeight

修正履歴

  • 2020/09/23 誤字と「理屈」の記述を一部修正しました。

    修正前:3がうまく機能しないのは

    修正後:3をスキップするとうまく行かないのは
2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?