2011-10-13 8 views
22

私はイベントハンドラを持っていますが、イベントキュー内の他のすべてのイベントが実行されるまで待ちます。他のすべてのイベントが処理された後にコードを実行する方法

たとえば、ページにいくつかのタブがあります。ユーザーがクリックするとタブを「アクティブなタブ」に設定するタブを処理する一般的なコードがあります。タブをクリックする以外の他のアクションに応じて呼び出されてしまうかもしれません)

// handler-1 
$('div#myTabs a.tab').click(function() { 
    do_something(); 
}); 

function do_something() { 
    var type = $('div#myTabs a.activeTab').data('type'); 
    do_something_else(type); 
} 

do_something(しかし、関係なく、どのようにそれをする:タブの特定のセットのために

$('a.tab').click(function() { 
    $(this).parent('div').find('a.tab').removeClass('activeTab'); 
    $(this).addClass('activeTab'); 
}); 

、私がハンドラを持っているかもしれませんアクティブになっているタブが継続できるかどうかを知りたがっています。

私の問題は、 '// handler-1'のコードで呼び出された場合、 'activeTab'クラスがまだリセットされていない可能性があるため、 'type'の値は引き続き取得されますこのタグをクリックする前に選択されたタグから。

私はこのようにそれを解決:

// handler-1 
$('div#myTabs a.tab').click(function() { 
    set_timeout(function() { 
    do_something(); 
    }, 100); 
}); 

をこれは私を満たすためにその場しのぎのあまりのように見えます。タイマーイベントハンドラは、他のハンドラがすべてターンした後にのみ呼び出されることをどのように知ることができますか?確かに「100」を「1000」に変更したり、「10000」に変更したりすることもできますが、パフォーマンスをより確実にすることもできます(ブラウザでは10秒でも不十分です十分に不自由な)。

私が見てきたいくつかの可能な解決策:

が、これらのいずれもが私を満たすのに十分な一般的なものです。私は最初にを実行するハンドラを取得しようとしていません。むしろ、私はこのようなものが欲しい:

function do_something() { 
    $.when_all_other_events_have_been_handled(function() { 
    do_something(); 
    }); 
}); 

このようなものはありますか?

私は$ .fn.when(arg).done()を見ましたが、何時ですか?この場合の "arg"は、既に実行キューにあるものを実行する遅延オブジェクトでなければなりません。キャッチ22!

Sproutcoreには、「エンジン」内の他のすべてのイベントが処理されたときにのみ返される「engine.run()」(正確な名前は記憶されません)というものがありますが、 jQueryで(http://api.jquery.com/category/events/)。誰かがそのようなことを知っているなら、私に知らせてください!

ありがとうございます! :)

答えて

27

はこれを試してみてください。

+0

ねえ!あなたは私自身の答えに私を打つ! –

+1

私はこれを正のタイムアウトで使用していましたが、それが競合状態であると考えて、それが有効であることを嬉しく思っています:) – Jake

+0

延期機能を使用するとエラーに直面しました:Ubuntu標準のためにFireFox 20.0で無駄なsetTimeout呼び出し1.0。@ lsidenの答えが私のために働いた。 –

25

私はここで答えを発見したことがあります。J.によるとhttp://ejohn.org/blog/how-javascript-timers-work/

を私は

setTimeout(function() { 
    do_something(); 
}, 0); 

をすればResig氏は、無名関数はすぐにenquedれますが、キューがすでに処理されたイベントで、他のすべてまでは呼び出されません。つまり、実行しているブラウザがあれば、私が期待するように先入れ先出しですべてを実行する限りです。何らかの理由でJavascriptエンジンがキュー内のイベントを並べ替えることになった場合(なぜそうすべきかはわかりませんが、AFAIK以来、私はスタンダードでそのような保証は見たことがないのですが、もう一度見てみる必要があります)、すべての賭けはオフです!あなたはdo_somethingpostpone()コールの瞬間のためのイベントキューにあるすべてのUIイベントの後に実行されることをpostpone(do_something);呼ぶならばそう

function postpone(fun) 
{ 
    window.setTimeout(fun,0); 
} 

+0

現時点ではChromeでこの現象は見られません。チェックボックスの「クリック」イベントで呼び出される2つの別々の関数があります。私は最後に私はsetTimeoutでラップしたいものですが、私が0に設定した場合、それは競合状態と思われます。私は500に設定し、それは動作するようだが、私はそれが運のみによって恐れる。 – Dss

関連する問題