2012-03-27 17 views
0

私はdivのクラスを持っています。MyClass最大2つのハンドラに接続します。このクラスは、動的に生成され、これは私がやっているものです:jqueryハンドラの順序を設定する

$('#MainDiv').on({ 
click: function() { Handler1($(this)); } 
}, '.MyClass'); 

$('#SpecialChildDiv').on({ 
click: function() { Handler2($(this)); } 
}, '.MyClass'); 

は、どのように私が最初に呼び出されるハンドラに制御しますか? Handler2はいくつかの追加作業を行いますが、SpecialChildDivにないため、すべてのMyClassで呼び出されるわけではありません。私は、Handler 2をAFTER Handler1と呼ぶことを望みます。

ありがとうございました。

+0

これは2つの異なるハンドラです...私はあなたが何を求めているのかよく分かりません... – Neal

+0

申し訳ありませんが、最後には「.myClass」が何をしていますか? http://api.jquery.com/on/ – Blazemonger

+0

私はそれが内側から働くと思う。 –

答えて

1

SpecialChildDivはおそらくMainDivの子孫であるので、それは最初に呼び出されます。これは、イベントがターゲットから飛びぬけて、その順序で途中で見つかったハンドラを呼び出すためです。

一つの可能​​性はsetTimeoutを使用してSpecialChildDivハンドラ非同期Handler2への呼び出しを行うことであろう。

$('#MainDiv').on({ 
    click: function() { 
     Handler1($(this)); 
    } 
}, '.MyClass'); 

$('#SpecialChildDiv').on({ 
    click: function() { 
     setTimeout($.proxy(function() { 
      Handler2($(this)); 
     }, this), 0); 
    } 
}, '.MyClass'); 

だから、ハンドラ自体はすぐに呼び出されますが、あなたのHandler2関数がHandler1が呼び出された後まで実行されません。

私はまた、に渡す関数で正しいthisの値を保持するために$.proxyを使用しました。


少しオフトピックが、あなたはthisではなく引数として渡すので、要素への参照であることをHandler1のでHandler2を変更する場合は、あなたのコードクリーナーを作ることができます...

$('#MainDiv').on({ 
    click: Handler1 
}, '.MyClass'); 

$('#SpecialChildDiv').on({ 
    click: function() { 
     setTimeout($.proxy(Handler2, this), 0); 
    } 
}, '.MyClass'); 

関数内で$(this)を実行するだけで、要素をjQueryオブジェクトにラップする必要があります。合格する他の議論があるなら、これは役に立たないかもしれませんが。


以下のコメントに基づいて、このテクニックをさまざまな子孫要素に適用する必要があるようです。

コードを乾燥させるために、あなたのクリックハンドラ...

function async_handler_factory(the_handler) { 
    return function() { 
     setTimeout($.proxy(function() { 
      the_handler($(this)); 
     }, this), 0); 
    }; 
} 

のファクトリを作成することができます...そして、このようにそれを使用して...

$('#MainDiv').on({ 
    click: Handler1 
}, '.MyClass'); 

$('#SpecialChildDiv').on({ 
    click: async_handler_factory(Handler2) 
}, '.MyClass'); 

$('#AnotherChildDiv').on({ 
    click: async_handler_factory(Handler3) 
}, '.MyClass'); 

だから、それはです同じ原則。ただHandlerN関数をasync_handler_factoryに渡して、setTimeoutHandlerNを呼び出すことで、元のコードと同じになるclickハンドラ関数を作成して返します。


だけ$.proxyについての混乱を避けるために、ここでそれを排除し、更新されたバージョンです。

function async_handler_factory(the_handler) { 
    return function() { 
     var self = this; 
     setTimeout(function() { 
      the_handler($(self)); 
     }, 0); 
    }; 
} 

これは、実際にあなたのソリューションの仕事をしているsetTimeoutだということを示しています。


EDIT:別の場所にasync_handler_factoryに別の名前を持っていました。一定。

+1

jqueryを作った人は本当にすべてを考えました!このプロキシ機能を紹介してくれてありがとう! – frenchie

+0

@frenchie:ようこそ。うん、 '$ .proxy'が便利だし、' var self = this; '' Handler2($(self)); ' –

+0

のように思っていたのですが、ちょっと考えました。それは他の方法の周りを動作させる?つまり、プロキシ機能をSpecialChildDivで動作させるのではなく、MainDivで動作させますか?実際にはいくつかの異なるSpecialChildDivがあり、私はすべてのケースでプロキシの問題を避けたいと思っています。 – frenchie

0

だからクリック上の第二1を呼び出すことはありません - 最初のハンドラが実行された後、それを呼び出す:

$('#MainDiv').on({ 
    click: function (e) { 
     Handler1($(this)); 
     if ($(e.target).attr('id')==="SpecialChildDiv") { 
      specialChildClick(); 
     } 
    } 
}, '.MyClass'); 

specialChildClick = function() { 
    Handler2($('#SpecialChildDiv')); 
} 
+0

はい、私はこれを行うことを考えましたが、私の場合は面倒です。 MyClassは実際にはカスタムカレンダーの日付であり、カレンダーのロジックをカレンダーを使用する他のコントロールのロジックとは別にしたいと考えています。 – frenchie

関連する問題