web-dev-qa-db-ja.com

直接対委任-jQuery .on()

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

selectorが指定されている場合、イベントハンドラーはdelegatedと呼ばれます。ハンドラーは、バインドされた要素でイベントが直接発生したときは呼び出されませんが、セレクターに一致する子孫(内部要素)に対してのみ呼び出されます。 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");
});

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

152
moey

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

364
N3dst4

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

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

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

5
nnnnnn

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

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

直接イベントまたはデリゲートイベントで機能します。

4

OPに接しているが、この機能との混乱を解く助けとなった概念は、バインドされた要素は選択された要素の親でなければならないである。

  • バウンドとは、_.on_の残りを指します。
  • 選択すると、.on()の2番目の引数が参照されます。

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

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

とは非常に異なります

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

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

編集

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

$('.bound').on('event', '.selected', some_function)が機能しない可能性があるトリッキーな理由:

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

(セレクターのつづりが間違っているなど、それほどトリッキーな理由は省略しています。)

2
Bob Stein

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

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

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

常に委任されたハンドラーを使用すると、現在非常にトレンディであることが正しい方法ではなく、多くのプログラマーは「使用する必要がある」ためそれを使用しますが、実際には、直接イベントハンドラーは状況によってはどのメソッドの使用をサポートする必要があるかにより良いということです違いの知識によって。

1
Maciej Sikora