2012-05-01 18 views
0

Javascriptスコープ規則を理解しているとは思えないので、助けが必要です。私が下の例でしようとしているのは、キーボード入力を聞き始めたページのボタンを押すことです。キーボード入力が開始されたら、入力が2秒間中断した場合、私は入力のキャプチャを停止し、そのポイントに収集された入力の完全な内容で警告をポップします。これは純粋にこの質問のために作った例です。Javascriptのオブジェクトメソッドとバインディング関数

私が見るのは、ボタンをクリックして入力を開始することです。キーを押すたびに、その時点までに収集された文字列が表示されます。 2秒後に、アクションなしのタイムアウトが発生し、内容が「未定義」のアラートが表示されます。上記の最初のアラートはstartLog()からのものです。 2番目の警告はstopLog()から発生します。私がstopLogを呼び出すと、this.messageが定義されていないことを私に伝えていると、私は間違って何をしていますか?

function Logger() { 
    this.message = ''; 
    this.listenTimer; 

    this.startLog = function() { 
     this.message = ''; 
     $(document).bind('keypress', {this_obj:this}, function(event) { 
      event.preventDefault(); 
      var data = event.data; 
      clearTimeout(data.this_obj.listenTimer); 
      data.this_obj.message += String.fromCharCode(event.which); 
      alert(data.this_obj.message); 
      data.this_obj.listenTimer = setTimeout(data.this_obj.stopLog, 2000); 
     }); 
    }; 

    this.stopLog = function() { 
     $(document).unbind("keypress"); 
     alert(this.message); 
    }; 
} 

var k = new Logger(); 
$('.logging-button').click(function() { 
    k.startLog(); 
}); 

答えて

0

問題はthisです。イベントハンドラとしてオブジェクトメソッドを渡すと、オブジェクトメソッドは失われます。 thiswindowオブジェクトを参照します。

あり、この問題を解決するための様々な方法がありますが、主な問題は、あなたがsetTimeoutにまだ正しいコンテキストを参照するクロージャを渡す必要があるということです。

setTimeout(function() { data.this_obj.stopLog() }, 2000); 

別のノートで、あなた自身を保存することができますただ、むしろevent.dataとしてそれを結合するよりも、オブジェクトを参照するためにクロージャを使用して、いくつかの不要なコード:

this.startLog = function() { 
    this.message = ''; 
    var this_obj = this; 
    $(document).bind('keypress', function(event) { 
     event.preventDefault(); 
     clearTimeout(this_obj.listenTimer); 
     // etc 
    }); 
}; 
+0

答えやヒントのためにありがとうございました。私のコードは今実行され、少しシャープに見えます。 – rebekswr

0
var k = new Logger(); 

$('.logging-button').click(function() { 
    k.startLog.apply(this); 
    //Setting context of "this" so that it refers to element even in startLog() 
}); 
関連する問題