166

jQuery .on()メソッドを使用して、直接イベントハンドラーと委任イベントハンドラーのこの特定の違いを理解しようとしています。具体的には、この段落の最後の文は次のとおりです。

aselectorが指定されている場合、イベントハンドラーは委任されたと呼ばれます。イベントがバインドされた要素で直接発生した場合、ハンドラーは呼び出されませんが、セレクターに一致する子孫(内部要素)に対してのみ呼び出されます。jQueryは、イベントターゲットからハンドラーがアタッチされている要素(つまり、最も内側の要素から最も外側の要素)までイベントをバブルし、セレクターに一致するパスに沿ったすべての要素に対してハンドラーを実行します。

「任意の要素に対してハンドラーを実行する」とはどういう意味ですか?コンセプトを試すためにテストページを作成しました。ただし、次の両方の構成により、同じ動作が発生します。

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

また、

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

たぶん誰かがこの点を明確にするために別の例を参照することができますか?ありがとう。

4

6 に答える 6

389

ケース1(直接):

$("div#target span.green").on("click", function() {...});

==ねえ!div#target内のすべてのspan.greenがリッスンするようにします。クリックされたら、Xを実行します。

ケース2(委任):

$("div#target").on("click", "span.green", function() {...});

==ねえ、div#target!「span.green」である子要素のいずれかがクリックされたら、それらでXを実行します。

言い換えると...

ケース1の場合、これらの各スパンには個別に指示が与えられています。新しいスパンが作成された場合、それらは指示を聞いておらず、クリックに応答しません。各スパンは、それ自体のイベントに直接責任があります。

ケース2では、コンテナのみに指示が与えられています。子要素に代わってクリックに気付く責任があります。イベントをキャッチする作業は委任されています。これは、将来作成される子要素に対して命令が実行されることも意味します。

于 2011-11-13T11:22:02.303 に答える
6

最初の方法は$("div#target span.green").on()、コードが実行された時点でセレクターと一致するスパンにクリックハンドラーを直接バインドします。これは、他のスパンが後で追加された場合(またはそれらのクラスが一致するように変更された場合)、それらは見逃されており、クリックハンドラーがないことを意味します。また、後でスパンの1つから「緑」のクラスを削除しても、クリックハンドラーは引き続き実行されます。jQueryはハンドラーがどのように割り当てられたかを追跡せず、セレクターがまだ一致するかどうかを確認します。

2番目の方法$("div#target").on()は、クリックハンドラーを一致するdivにバインドします(これも、その時点で一致するdivに対してです)が、divのどこかでクリックが発生すると、ハンドラー関数はクリックが発生した場合にのみ実行されます。 divだけでなく、2番目のパラメーターのセレクターが.on()「span.green」に一致する子要素で発生しました。このようにすると、子スパンがいつ作成されたかは関係ありません。子スパンをクリックしても、ハンドラーが実行されます。

したがって、コンテンツを動的に追加または変更していないページの場合、2つの方法の違いに気付くことはありません。子要素を動的に追加する場合、2番目の構文は、親で一度行ったことがあるので、クリックハンドラーをそれらに割り当てることを心配する必要がないことを意味します。

于 2011-11-13T11:03:55.573 に答える
6

N3dst4の説明は完璧です。これに基づいて、すべての子要素がボディ内にあると想定できるため、これのみを使用する必要があります。

$('body').on('click', '.element', function(){
    alert('It works!')
});

ダイレクトイベントまたはデリゲートイベントで機能します。

于 2014-04-25T16:42:17.820 に答える
3

OPに正接しますが、この機能との混乱を解くのに役立った概念は、バインドされた要素が選択された要素の親である必要があるということです。

  • バウンドとは、の残りを指し.onます。
  • Selectedは、の2番目の引数を参照し.on()ます。

委任は.find()のようには機能せず、バインドされた要素のサブセットを選択します。セレクターは、厳密な子要素にのみ適用されます。

$("span.green").on("click", ...

とは大きく異なります

$("span").on("click", ".green", ...

特に、@ N3dst4が「将来作成される要素」で示唆する利点を得るには、バインドされた要素が永続的な親である必要があります。その後、選択した子供たちが行き来することができます。

編集

委任.onが機能しない理由のチェックリスト

うまくいかないかもしれないトリッキーな理由$('.bound').on('event', '.selected', some_function)

  1. バインドされた要素は永続的ではありません。呼び出し後に作成されました.on()
  2. 選択された要素は、バインドされた要素の適切な子ではありません。それは同じ要素です。
  3. 選択された要素は、を呼び出すことにより、バインドされた要素へのイベントのバブリングを防止しました.stopPropagation()

(セレクターのスペルミスなど、トリッキーでない理由を省略します。)

于 2016-01-27T16:01:17.437 に答える
1

直接のイベントと委任されたイベントを比較して投稿を書きました。私は純粋なjsを比較しますが、それをカプセル化するだけのjqueryでも同じ意味を持ちます。

結論として、委任されたイベント処理は、ユーザーがページを操作している間にバインドされた要素を作成できる動的DOM構造用であり(再度バインドする必要はありません)、構造が変更されないことがわかっている場合、直接イベント処理は静的DOM要素用です。

詳細と完全な比較については -http://maciejsikora.com/standard-events-vs-event-delegation/

常に委任されたハンドラーを使用することは、現在非常に流行しているため、正しい方法ではありません。多くのプログラマーは、「使用する必要がある」ためにこれを使用しますが、実際には、状況によっては直接イベントハンドラーの方が適しているため、どのメソッドを使用するかを選択できます。違いの知識によって。

于 2016-09-06T12:54:12.200 に答える
0

ケース3(委任):

$("div#target").delegate("span.green", "click", function() {...});
于 2021-01-11T16:21:06.653 に答える