以前、テキストエリアのサイズを文章の長さに合わせて変えるスクリプトを考えて、それをppBlogのエディタにも採り入れているのですが、それは意図した様に動くには動くのですが、えらく力業なスクリプトでした。その恥ずかしいスクリプトは、ここ に置いてます
記述も長くてスマートでないし、もっと簡単に出来ないかなぁと考えてみましたが、要は、自動調節というのは、テキストエリアのスクロールバーが表示されなくなるまでエリアを伸ばすということなので、その考えで行けば簡単でした。以下のような記述でいけますね。
function autofit(el){ if(el.scrollHeight > el.offsetHeight){ el.style.height = el.scrollHeight + 'px'; } }
element.scrollHeightで、目的のテキストエリアの、スクロール分も含めた高さ(+ボーダー幅)を取得できます。で、element.offsetHeightで、見た目の高さを取得できます。なので、スクロールバーが表示されている状態というのは、文章が長くて表示しきれない状態なので、じぁ、テキストエリアの高さをscrollHeightに合わせれば良い、ということになりますね。なんで、こんな簡単なことに気が付かなかったかなぁ。まず、このデモを見てみましょう。
とりあえずは、これでよさげですが、もうちょっといじってみましょう。例えば、この文章をコピペして、元の文章の下に貼り付けると、表示領域からはみ出るので、自動的にスクロールバーが表示されると思います。なので、ここでもう一度「AutoFit」ボタンを押すと、テキストエリアが広がります。次に、この貼り付けた文章を削除してみて下さい。テキストエリアが広がった分、下に大きな余白が出来ますね。今度は縮めようと再度ボタンを押してもテキストエリアのサイズは変わりません。これは、このautofit関数の定義からして当然なのですが、気持ちとしては、今度は逆に縮んで欲しいなと。では、どうするか?
強制的にスクロールバーを表示させる状態に持っていって、そこでこのautofit関数をかませば良いです。スクロールバーを表示させるには、意図的にテキストエリアの縦サイズを小さく取ればよいわけです。なので、極端な話、
element.style.height = '1em';
とでもして、つぎにautofit()を呼び出せばOKですが、これだと見た目にテキストエリアがスプラッシュみたくなるので、なるべく最小量のサイズ変更でいくには、次のような感じで良いかなと思います。
/* AutoFit関数その2 */ function autofit2(el){ if(el.scrollHeight > el.offsetHeight){ el.style.height = el.scrollHeight + 'px'; } else { while (el.scrollHeight - 50 < parseInt(el.style.height)){ el.style.height = parseInt(el.style.height) - 50 + 'px'; // 適当に50pxずつ } arguments.callee(el); // 高さを縮めてスクロールバーが出てくるタイミングで呼び出す } el.focus(); }
以下に、これを適用したものを付けておきます。上の関数との動作の違いが分かると思います。
この関数をonkeyupなどのキーイベントと結びつけておけば、入力に合わせて自動的にサイズが変わるテキストエリアの出来上がりです。これのデモを以下に挙げておきます。
→http://p2b.jp/demo/autofit-textarea.html
Comments