内容の分量に応じて、textareaの自動サイズ変更(高さ)をするスクリプトを書きました。
本来ならばjQuery Autosizeという素敵ライブラリがあるのですが、なぜだかこれが上手く動かなくて泣く泣く自前で作る羽目に。
一応、自分用にはjQueryを使って書いたんですが、jQueryを使わないバージョンも書いてみました。
<textarea id="ta"></textarea>
//jquery使うバージョン
$("#ta").height(30);//init
$("#ta").css("lineHeight","20px");//init
$("#ta").on("input",function(evt){
if(evt.target.scrollHeight > evt.target.offsetHeight){
$(evt.target).height(evt.target.scrollHeight);
}else{
var lineHeight = Number($(evt.target).css("lineHeight").split("px")[0]);
while (true){
$(evt.target).height($(evt.target).height() - lineHeight);
if(evt.target.scrollHeight > evt.target.offsetHeight){
$(evt.target).height(evt.target.scrollHeight);
break;
}
}
}
});
//jquery使わないバージョン
var ta = document.getElementById("ta");
ta.style.lineHeight = "20px";//init
ta.style.height = "30px";//init
ta.addEventListener("input",function(evt){
if(evt.target.scrollHeight > evt.target.offsetHeight){
evt.target.style.height = evt.target.scrollHeight + "px";
}else{
var height,lineHeight;
while (true){
height = Number(evt.target.style.height.split("px")[0]);
lineHeight = Number(evt.target.style.lineHeight.split("px")[0]);
evt.target.style.height = height - lineHeight + "px";
if(evt.target.scrollHeight > evt.target.offsetHeight){
evt.target.style.height = evt.target.scrollHeight + "px";
break;
}
}
}
});
ちなみに、height
だとかlineHeight
だとかの項目は上記の例のようにプログラム中で指定するか、CSSで設定してあげる必要があります。
どちらもやってることは同じなので、jQueryの方を使って説明します。
//jquery使うバージョン
$("#ta").on("input",function(evt){
//...
});
まず、input
イベントに反応するようにリスナを設定します。
if(evt.target.scrollHeight > evt.target.offsetHeight){
$(evt.target).height(evt.target.scrollHeight);
}
次に、scrollHeight
(入力内容全体)とoffsetHeight
(要素の大きさ)とを比較して、入力内容の方が大きい場合は、textareaのheight
をscrollHeight
に合わせるようにします。これで、改行をしたり、文字数が増えて行を跨いだときなどに、自動的にtextareaのheight
を増やし、入力内容の大きさに合わせてくれます。
else{
var lineHeight = Number($(evt.target).css("lineHeight").split("px")[0]);
while (true){
$(evt.target).height($(evt.target).height() - lineHeight);
if(evt.target.scrollHeight > evt.target.offsetHeight){
$(evt.target).height(evt.target.scrollHeight);
break;
}
}
}
逆に、scrollHeight
の方がoffsetHeight
よりも小さい、あるいは同じ場合には、height
を減らしていきます。textareaのheight
を1ラインずつ減らしていき、scrollHeight
がoffsetHeight
よりも大きくなったところでheight
をscrollHeight
に合わせるようにします。
なぜこんなことをしているかというと、offsetHeight
からはみ出させないと、scrollHeight
を入力内容の大きさとして扱えないからです。textarea内全ての入力内容がスクロールすることなく見えている場合、scrollHeight
はclientHeight
と同じ値をとってしまいます。
以上です。
何かの参考になれば幸いです。
*参考*
・jsStudio scrollHeight
・MDN Element.scrollHeight
・MDN HTMLElement.offsetHeight