2013-01-05 3 views
10

jQueryの.on()メソッドをネイティブJSでどのように実装できるか知っていますか? "addEventListener"メソッドはフィルタリングの方法として子要素/セレクタ要素をとらないため、そこで何が起こっているのかを完全に理解するための適切なバブリング/キャプチャの知識はないと思います。私はevent.jsのソースを参照しましたが、最終的にaddEventListenerは通常のように使用されるように見えますが、ソースをかなりgrokしているかどうかはわかりません。jQueryで.on()のようなセレクタを持つネイティブのaddEventListener

ネイティブメソッドでバブリングとキャプチャを利用するためのメカニズムが提供されていない場合、jQuery .on()関数は実際には何のメリットもありますか?私は

.on('parent', '.child', fn(){}); 

が個別にすべての子供たちにイベントをアタッチするよりも効率的であるという印象の下にあったが、元の私の解釈から、それはjQueryのは、何らかの形で、パフォーマンスへのリードと方法でこれを管理しているかどうか言うことは困難です改善、または読みやすさのためだけの場合

個々の子にイベントを添付するのではなく、子要素のバブリング/キャプチャフェーズを利用するイベントを親に実装するための標準的な方法がありますか?

+2

もしあなたが '.on()'の仕組みを理解していなければ、実際にその性能を判断することはできません – Alexander

+3

イベントについて知りたいことをすべて学ぶには:http://www.quirksmode.org/ js/introevents.html。あなたの質問について:あなたが欲しいものは* event delegation *と呼ばれ、実際にはとても簡単です。任意の親に偶数ハンドラを付け、ターゲットノード( 'event.target')があなたの条件を満たしているかどうかをチェックします。 –

+2

* related:* [DOM Event delegationとは何ですか?](http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) –

答えて

11

ネイティブイベントの委任を実行するには:

parent.addEventListener('click', function(e) { 
    if(e.target.classList.contains('myclass')) { 
     // this code will be executed only when elements with class 
     // 'myclass' are clicked on 
    } 
}); 

をあなたが参照している効率は、追加どのように多くのイベントハンドラに関係しています。 100行の表を想像してみてください。 1つのイベントハンドラをテーブル要素にアタッチし、100行のイベントハンドラをアタッチするよりも各行に「委任」する方が効率的です。

イベント委任の理由は、クリックイベントが実際に子と親の両方で発生するためです(親内の領域をクリックしているため)。上記のコードスニペットは、親のclickイベントで発生しますが、イベントターゲットに対して条件がtrueを返し、直接接続されたイベントハンドラをシミュレートする場合にのみ実行されます。

バブリング/キャプチャは関連する問題ですが、複数のイベントハンドラの実行順序が問題になる場合は、気にする必要があります。キャプチャとバブリングを理解することに興味があるなら、event orderをさらに読むことをお勧めします。

イベント委任の最も一般的な利点は、イベントハンドラが添付された後にDOMに追加される新しい要素を処理することです。上記の100行のテーブルの例をクリックハンドラで取得します。ダイレクトイベントハンドラアタッチメント(100個のイベントハンドラ)を使用すると、追加される新しいローには、手動でイベントハンドラを追加する必要があります。委譲されたイベントを使用すると、新しい行は自動的にイベントハンドラを持つことになります。これは、技術的に親に追加されているため、将来のすべてのイベントを取得します。詳細については、Felix Kling氏が提案したWhat is DOM Event Delegationをお読みください。

+0

これは意図せずに ".myclass2"という名前のクラスを選択します。 –

+1

良いキャッチです。私が言った他のすべてはまだ関連しているはずです。 –

+0

(e.target.classList.contains(」。MyClassの '))場合condintialは '' ' に書き換え中することができ ' '' –

関連する問題