テキストエリアの自動リサイズ再び

category-icon

 以前、テキストエリアのサイズを文章の長さに合わせて変えるスクリプトを考えて、それをppBlogのエディタにも採り入れているのですが、それは意図した様に動くには動くのですが、えらく力業なスクリプトでした。その恥ずかしいスクリプトは、ここLink に置いてます?;w)

 記述も長くてスマートでないし、もっと簡単に出来ないかなぁと考えてみましたが、要は、自動調節というのは、テキストエリアのスクロールバーが表示されなくなるまでエリアを伸ばすということなので、その考えで行けば簡単でした。以下のような記述でいけますね。

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.htmlLink

— posted by martin at 05:30 am   commentComment [2]  pingTrackBack [0]

この記事に対するコメント・トラックバック [2件]

scrollUp1. BENIT — 2009/03/23@08:10:46

おはようございます、BENITです。
ひとつ要望を上げさせてください。
ローカルプレビュー時に、プレビュー枠のなかに表示される「この内容を修正」のアイコンにかかっているリンクを外して欲しい、という内容になります。
押さなければ良い、というのは重々承知なのですが、先日誤って押してしまい、書いていたエントリが消えてしまいました。そういうときに限ってAutoSaveを押していなかったという(TT)
誤操作で書いているエントリが消えてしまう可能性がある、というのは言いすぎですが、実際問題として、「この内容を修正」や「削除」のアイコンは、プレビュー時に機能している必要はないと思います。
お忙しいところ恐れ入りますが、ご検討いただければと思います。

P.S 1.8.0のリリースはいつごろでしょうか?

Owner Comment martin Website  2009/03/23@20:05:49

こんにちは。残念な思いをさせてしまいすみません。実は、こちらもローカルのテスト環境で同じことをやり、その対策は入れていたと思いますが(去年の10月末ぐらい?)、もっと、幅広く制御した方がよいですね。これは、editor.jsのpreViewAreaOn()関数をいじると良いです。ARTICLE_BOX = ARTICLE_BOX.replace...というのがあると思いますが、これを

ARTICLE_BOX = ARTICLE_BOX.replace(/<a href="admin.php¥?mode=edit.+?<¥/a>/, '').replace(/ href="[^"]+?"/g, ' href="#" onclick="return false;"');

とすれば、リンク「表示」は有効のままで、クリックしても反応しないという感じになるかと思います。カテゴリーだとか、コメントやTBのリンクに対してです。文章中の外部リンクは、プレビューでも有効です(これは別タブで開くでしょうから)。

 1.8.0のリリースですが、手を加えた箇所が多岐に渡るので、とりあえず「試用版」として、今夜あたりリリース出来たらと思っています。結構、書き換えたりしてますからねぇ。

この記事に対する TrackBack URL:

設定によりTB元のページに、こちらの記事への言及(この記事へのリンク)がなければ、TB受付不可となりますのであらかじめご了承下さい。

コメントをどうぞ。 名前(ペンネーム)と画像認証のひらがな4文字は必須で、ウェブサイトURLはオプションです。

ウェブサイト (U):

タグは使えません。http://・・・ は自動的にリンク表示となります

:) :D 8-) ;-) :P :E :o :( (TT) ):T (--) (++!) ?;w) (-o-) (**!) ;v) f(--; :B l_P~

     
T: Y: ALL: Online:
Created in 0.0042 sec.
prev
2019.3
next
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31