(Twitter風に)入力文字数をカウントするスクリプト


基本戦略としてはタイマーで文字数を監視して画面に表示するだけです。

(追記:「キーイベントじゃないの?」とtwitterで聞かれたんですけど、貼り付けのときにも数字を更新したいので、タイマーで監視するようにしています。)

DEMO

ただフォーカスを得ていないときは監視する意味が無いので、

  1. フォーカスを得たら監視を開始する
  2. フォーカスを失ったら監視を終了する

というようにはしています。

また細かいところとして、監視処理を無名関数で実装して即時実行しています。そこからarguments.calleeを使って実行関数自身setTimeout()に渡してタイマー起動を行っています。このあたりは過去の記事、JavaScriptで、定期的に呼び出される処理を簡単に作るをご覧ください。

    var elContent = $('#tweeting-content');
    var elCounter = $('#tweeting-counter');
    elContent.
        // フォーカスを得た際に、監視開始
        focus(function() {
            (function() {
                // 残数を取得
                var MAX = 140;
                var count = elContent.val().length;
                var rest = MAX - count;

                // 数値を更新
                elCounter.text(rest);

                // 負数になったら赤字にする
                if (rest < 0) {
                    elCounter.css({ color: '#c00' });
                }
                else {
                    elCounter.css({ color: '' });
                }

                // 同じ処理をタイマーで実行
                // (タイマーIDは要素に紐付けて保存する。)
                var tm = setTimeout(arguments.callee, 100);
                elContent.data('tmCountLetters', tm);
            })();
        }).
        // フォーカスを失った際に、監視終了
        blur(function() {
            var tm = elContent.data('tmCountLetters');
            clearTimeout(tm);
        });

なお実際にこのスクリプトを使う場合は、通常のユーザー入力以外のタイミングで内容が変化する可能性を考慮してください。以下がよくあると思います。

  • ブラウザによる、画面更新時の入力内容の復帰
  • フォーム入力内容のリセット(入力キャンセルだけでなく、内容を動的に送信した後のリセットも)

そうそう、残り0を下回ると色を変えるようにしているんですが、これも本来なら色指定の変更ではなくクラス名の変更で管理するべきですね。