« Tag入力Suggestテスト | メイン | クロージャの使用例 in Text::Hatena »

Form.Element.Observerの自動停止

Form.Element.Observerはprototype.jsが提供する機能で、指定した間隔でフィールドをチェックして内容に変化があればcallbackを実行してくれるものです。
一つ前のエントリーで書いた「Tag入力Suggestテスト」でTagの入力の捕捉に利用してます。

Form.Element.Observerでちょっと気になるのは、指定した間隔でフィールドをチェックするTimerの停止ができないところです。Femoだとフォームが表示されたり消えたりとするので、timerを停止できたほうがCPUやメモリーにやさしいと思われ。

Timerのセットは、Form.Element.Observerの上位クラスであるAbstract.TimedObserverで

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

こんなように書かれています。intervalを呼び出す機能しかありません。
なので、この辺りをすこし書き加えて、確認対象のフィールドがなくなったらclearintervalされるようにしました。

Form.Element.Observer.prototype.registerCallback=function(){
    this.interval = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
};
Form.Element.Observer.prototype.clearTimerEvent=function(){
    clearInterval(this.interval);
};
Form.Element.Observer.prototype.onTimerEvent=function(){
    try{
        var node = this.element.parentNode.tagName;
    }catch(e){
        this.clearTimerEvent();
    }    
    var value = this.getValue();
    if (this.lastValue != value) {
        this.callback(this.element, value);
        this.lastValue = value;
    }
};

と、してみました。

確認ですが、

<div id="text1div">
Text:<input type="text" name="text1" id="text1" size="50">
</div>
<p><a href="JavaScript:void(0);" onClick="$('text1div').innerHTML='deleted'">消す</a></p>
<script type="text/javascript">
new Form.Element.Observer($('text1'),1,function(){alert('foo')});
</script>

というHTMLを用意して、ブラウザで表示。「消す」をクリック。
この状態で、

var node = this.element.parentNode.tagName;

がエラーとなってclearintervalが行われました。

動いたんだけど、

    try{
        var node = this.element.parentNode.tagName;
    }catch(e){
        this.clearTimerEvent();
    }    

これが微妙ですよね。

何かいい方法ないかなぁ。