prototype.jsを読み解く

第10回 Prototypeライブラリ(2846~3276行目)

この記事を読むのに必要な時間:およそ 15 分

最終回

この連載も今回が最終回です。

単に季節物のPrototypeライブラリを解説する,という視点ではなく,今後ライブラリのバージョンがさらにあがっても応用できるような基礎知識や,深追いするためのヒントなどを織り交ぜてきたつもりです。

「あとで読む」つもりの方も多いかと思いますが,読むのを忘れないでもらえれば幸いです。:-))

では,最後まで一気に行きましょう。

Abstract.TimedObserver オブジェクト

2846: Abstract.TimedObserver = function() {}
2847: Abstract.TimedObserver.prototype = {
2848:   initialize: function(element, frequency, callback) {
2849:     this.frequency = frequency;
2850:     this.element   = $(element);
2851:     this.callback  = callback;
2852: 
2853:     this.lastValue = this.getValue();
2854:     this.registerCallback();
2855:   },
2856: 

2846行目からはAbstract.TimedObserverです。

Form.Element.Observer,Form.Observerのprototypeとして使われます。ベースクラスとして使われるだけなので,このオブジェクト自体はClass.create()されずに単なるオブジェクト({})として初期化されています。

よって,2848行目からのinitialize()メソッドはForm.Element.Observer, Form.ObserverオブジェクトがClass.create()で初期化されることで,共通して利用されるコンストラクタとなります。

コンストラクタの中身は,まずインスタンス変数に引数を格納し,各派生クラスで定義されている getValue() を呼んで現状の値を保存しています。渡されたパラメータに基づいて registerCallback()メソッドを呼び出して,その中で定期的なタイマーをsetInterval()で設定しています。

2857:   registerCallback: function() {
2858:     setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
2859:   },
2860: 

そのregisterCallback()です。前述したように,単にsetInterval()を呼んでいるだけです。特に特徴的な所も無く,this.メソッド名.bind(this)の慣用句を使っているくらいです。

2861:   onTimerEvent: function() {
2862:     var value = this.getValue();
2863:     var changed = ('string' == typeof this.lastValue && 'string' == typeof value
2864:       ? this.lastValue != value : String(this.lastValue) != String(value));
2865:     if (changed) {
2866:       this.callback(this.element, value);
2867:       this.lastValue = value;
2868:     }
2869:   }
2870: }
2871: 

2861行目からはタイマーイベントごとに呼ばれるonTimerEvent()メソッドです。

まずgetValue()で最新の値を取得します。Form.Element.Observerの場合はgetValue()がnullを返す可能性があるので,それも考慮してlastValueから変化があったかどうかをchangedに入れます。

あとは変化した場合にコンストラクタから渡されたコールバック関数を呼び,次のためにlastValueを上書きして終了です。

Form.Element.Observer クラス

2872: Form.Element.Observer = Class.create();
2873: Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
2874:   getValue: function() {
2875:     return Form.Element.getValue(this.element);
2876:   }
2877: });
2878: 

2872行目からはForm.Element.Observerクラスです。

フォームの入力要素を定期的に監視し,変化があった場合にコールバック関数を呼び出します。

実装はClass.create()で雛形を生成し,prototypeに先ほどのAbstract.TimedObserver.prototypeとこのクラス固有のgetValue()メソッドをマージしたものを代入します。

getValue()メソッドでは,Form.Element.getValue()を使って入力要素の値を取得しています。

Form.Observer クラス

2879: Form.Observer = Class.create();
2880: Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
2881:   getValue: function() {
2882:     return Form.serialize(this.element);
2883:   }
2884: });
2885: 
2886: /*--------------------------------------------------------------------------*/
2887: 

2879行目からはForm.Observerクラスです。こちらはフォーム全体を監視します。

Form.Element.Observerと同様にAbstract.TimedObserverから継承し,getValue()には Form.serialize()を使ってフォーム全体の値を文字列として取得しています。

著者プロフィール

栗山淳(くりやまじゅん)

S2ファクトリー株式会社株式会社イメージソース所属。
本業はWeb制作会社の裏方。得意分野はFreeBSDやPerlのはずだが,必要に迫られるとHTML/CSSやJavaScriptも書く。

コメント

コメントの記入