[js]textareaの高さを改行したときに自動調整する

入れると親切かもしれない。

動作イメージ

例えばtextareaの高さが3行分だったとする。

改行して4行目以降に突入すると、通常はtextareaの高さは変わらずに右側にスクロールバーが表示される。先頭行が隠れちゃうのでドラッグして領域を広げる。

これを、twitterとかchatworkとかLINEとかみたいに、スクロールバーを出さずにtextareaをサイズアップさせたい。つまりtextarea内に入力したものはすべて常に隠れずに表示されるということになる。

やっていく

とりあえずベースはこんな感じ。

<style>
    textarea#target{height: 3em;}
</style>
<textarea id="target"></textarea> 

初期状態として3行分の高さを指定してある。

で、こう。

$(function(){
    $('textarea#target').on('input',function(){
        var lines = $(this).val().match(/\n/g).length;
        $(this).css('min-height',lines + 1 + 'em');
    })
})

入力時に行数(\nの数)をチェックして、それに+1した高さをcssを挿入して変更する。

4行目以降はtextareaが1行分ずつ高くなり、それから改行を削除するとその分低くなる。

min-heightにしてあるのはtextareaを初期の高さ以下にさせないため。height、max-heightで指定する2行目に改行したときにtextareaの高さが低くなる。

注意点

textareaをドラッグして拡張した場合、最初に設定した3行から高さ(height)が変更される。なので、min-heightがどう変わったところでそのサイズ以下にはならない。

そうすると初期の高さを1行にしてjsでheightを変更するのがいい。動作的にTwitterっぽくなる。

ただし1行だけのtextareaはリスクがある。twitterやらChatworkやらは「そういうもの」として理解されるのでいいんだけど、textareaは基本的に問い合わせフォームとかで他のinputとセットで使うわけで、inputと見間違えられるとだるい。ユーザーが感覚的に分かるようにするために高さは1行にしちゃいけない。

なので、高さをドラッグで変えられないようにcssで制御することもセットにしたほうがいいと思うの。

textarea {
  resize: none;
}

ついでに装飾として、transitionを入れておくと伸び縮みのアニメーションが追加されるので、なんかちょっとリッチな感じがしますね。アニメーション中はスクロールバーが表示されてダサいからoverflowも足さなきゃだけど。

textarea{
    height: 3em;
    resize: none;
    overflow: hidden;
    transition: all .2s;
}

なんかそんなかんじで。

コメント

タイトルとURLをコピーしました