2012-04-03 4 views
1

私は検索して検索しましたが、私はこの1人で空になります。助けて! JQuery on()を使用してキーアップイベントの入力フィールド(#filter_query)を見ています。ユーザがこの入力フィールドに何らかのテキストでパンチインすると、on()はsetTimeout()をトリガし、次にそれがサイトの検索機能をトリガします。私はユーザーが入力フィールドに入力し続けてclearTimeout()を実行した場合、検索が実行されないようにしようとしています。何らかの理由で、タイムアウトIDがclearTimeoutに保存されず、そのたびに新しいIDが生成されます。私の検索機能はてclearTimeoutに関わらず、数回をオフに解雇されている上記のコードではJavascript - JQuery on()clearTimeoutスコープの問題

$(document).on('keyup', '#filter_query', function (event) { 
    var iTimeoutID, 
     iTypingDelay = 800, 
     sFilterVal = $.trim($('#filter_query').val()), 
     sFilterCat = $('#filter_catagory').val(), 
     sFilterCol = $('#filter_col').val(); 

    clearTimeout(iTimeoutID); 

    if (sFilterVal !== "") { 
     iTimeoutID = setTimeout(
        function() { 
         searchFunction(); 
        }, 
        iTypingDelay 
        ); 
    } 
}); 

():

は、ここに私のコードです。ありがとうございました!

答えて

0

iTimeoutIDは、.on()イベントハンドラ関数のローカル変数であるため、その関数が完了して次回に再作成されるたびに破棄されます。 1つのイベントから次のイベントまで生き残るために、そのスコープから上位レベルまたはグローバルレベルに移動します。

このようにすることができます。

var iTimeoutID = null; 
$(document).on('keyup', '#filter_query', function (event) { 
    var iTypingDelay = 800, 
     sFilterVal = $.trim($('#filter_query').val()), 
     sFilterCat = $('#filter_catagory').val(), 
     sFilterCol = $('#filter_col').val(); 

    if (iTimeoutID) { 
     clearTimeout(iTimeoutID); 
     iTimeoutID = null; 
    } 

    if (sFilterVal !== "") { 
     iTimeoutID = setTimeout(function() { 
      iTimeoutID = null; 
      searchFunction(); 
     }, iTypingDelay); 
    } 
}); 

あなたはグローバル変数を回避したいか、あなたがこれらの複数を持っている場合は、あなたがこのようなオブジェクト上のタイマIDを保存するためにjQueryの.data()を使用することができます。

$(document).on('keyup', '#filter_query', function (event) { 
    var self = $(this); 
    var iTimeoutID = self.data("timerID") || null; 
    var iTypingDelay = 800, 
     sFilterVal = $.trim($('#filter_query').val()), 
     sFilterCat = $('#filter_catagory').val(), 
     sFilterCol = $('#filter_col').val(); 

    if (iTimeoutID) { 
     clearTimeout(iTimeoutID); 
     iTimeoutID = null; 
    } 

    if (sFilterVal !== "") { 
     iTimeoutID = setTimeout(function() { 
      self.data("timerID", null); 
      searchFunction(); 
     }, iTypingDelay); 
    } 
    self.data("timerID", iTimeoutID); 
}); 

ここで一つの他のバージョンがありますそれは、グローバルされずにイベントハンドラ間で最後にすることができ、いくつかの変数のためのシェルとして機能するように、自己実行機能を使用しています。

(function()() { 
    var iTimeoutID = null; 
    $(document).on('keyup', '#filter_query', function (event) { 
     var iTypingDelay = 800, 
      sFilterVal = $.trim($('#filter_query').val()), 
      sFilterCat = $('#filter_catagory').val(), 
      sFilterCol = $('#filter_col').val(); 

     if (iTimeoutID) { 
      clearTimeout(iTimeoutID); 
      iTimeoutID = null; 
     } 

     if (sFilterVal !== "") { 
      iTimeoutID = setTimeout(function() { 
       iTimeoutID = null; 
       searchFunction(); 
      }, iTypingDelay); 
     } 
    }); 
})(); 

これは何かQUICだった場合kと他のコードとの競合の可能性はほとんどなく、イベントハンドラによって提供されるオブジェクトは1つだけです。最初のオプションは完全にうまくいきます。

.on()イベントハンドラが複数のオブジェクトを処理し、それぞれが自身の状態を追跡する必要がある場合は、2番目のオプションが最適です。

同じイベントハンドラに複数のオブジェクトがない場合は、新しいグローバル変数を追加しないでおくのが最も簡単な方法です。

+0

ねえ、ありがとう!これはうまくいくでしょう。 – Nykad

+0

もう1つのオプションが追加されました。イベントハンドラを越えて持続する非グローバル変数のシェルとして機能する自己実行匿名関数です。 – jfriend00

0

変数var iTimeoutIDを定義しているため、グローバル変数ではなく、その関数内でのみアクセス可能です。関数が再び呼び出されると、新しい変数が作成されます。

変数var iTimeoutIDを宣言しないことで修正できるはずです。

私は間違っているかもしれないので、もし誰かが私を修正してください。

+0

私はいつもそのようなグローバル変数を使用することはお勧めしませんでした。私は間違っていますか?もしそうなら、グローバル変数を宣言するためのベストプラクティスは何ですか? – Nykad

+0

jfriend00答えが良いです。それを読んでください。 – LeeR