JQueryを初めて学んだとき、通常は次のようなイベントを添付しました。
_$('.my-widget a').click(function() {
$(this).toggleClass('active');
});
_
セレクターの速度とイベントの委任についてさらに学習した後、「jQueryイベントの委任によりコードが高速化される」ことをいくつかの場所で読みました。そこで、次のようなコードを書き始めました。
_$('.my-widget').on('click','a',function() {
$(this).toggleClass('active');
});
_
これは、廃止された.live()イベントの動作を複製する推奨方法でもありました。私の多くのサイトは常に動的にウィジェットを追加/削除するので、これは私にとって重要です。ただし、既に存在するコンテナ '.my-widget'に追加された要素のみが動作を取得するため、上記は.live()とまったく同じようには動作しません。そのコードの実行後にhtmlの別のブロックを動的に追加すると、これらの要素はそれらにバインドされたイベントを取得しません。このような:
_setTimeout(function() {
$('body').append('<div class="my-widget"><a>Click does nothing</a></div>');
}, 1000);
_
次のようにすべてのイベントを添付します。
_$(document).on('click.my-widget-namespace', '.my-widget a', function() {
$(this).toggleClass('active');
});
_
これは私のすべての目標を達成しているようです。 (はい、IEで遅いですが、理由はわかりませんか?)単一のイベントのみが単一の要素に結び付けられ、セカンダリセレクターはイベントが発生したときにのみ評価されるため、高速です(お願いしますここでこれが間違っている場合は修正してください)名前空間は、イベントリスナーを簡単に切り替えることができるので素晴らしいです。
だから、jQueryイベントは常に$(document)にバインドされるべきだと考え始めています。
これをしたくない理由はありますか?
これはベストプラクティスと考えられますか?そうでない場合、なぜですか?
このすべてを読んだなら、ありがとう。フィードバック/洞察に感謝します。
仮定:
.on()
をサポートするjQueryの使用//少なくともバージョン1.7測定値/例:
いいえ-すべての委任されたイベントハンドラーをdocument
オブジェクトにバインドしないでください。これはおそらく、作成できる最悪のパフォーマンスシナリオです。
まず、イベントの委任が常にコードを高速化するとは限りません。ある場合には、それは有利であり、ある場合にはそうではありません。実際にイベントの委任が必要な場合、およびそれから利益を得る場合は、イベントの委任を使用する必要があります。それ以外の場合は、イベントハンドラーをイベントが発生するオブジェクトに直接バインドする必要があります。これは一般に効率的だからです。
次に、すべての委任されたイベントをドキュメントレベルでバインドしないでください。これは、.live()
が非推奨になった理由です。この方法で多くのイベントがバインドされている場合、これは非常に非効率的です。委任されたイベント処理では、動的ではない最も近い親にバインドする方がはるかに効率的です。
第三に、すべてのイベントが機能するわけではなく、すべての問題が委任で解決できるわけでもありません。たとえば、入力コントロールのキーイベントをインターセプトし、無効なキーが入力コントロールに入力されるのをブロックする場合、デリゲートハンドラーにイベントがバブルアップするまでに、デリゲートハンドラーでそれを行うことはできません。入力コントロールによって処理され、その動作に影響を与えるには遅すぎます。
イベントの委任が必要または有利な場合は次のとおりです。
これをもう少し理解するには、jQueryの委任イベントハンドラーの動作を理解する必要があります。このようなものを呼び出すとき:
_$("#myParent").on('click', 'button.actionButton', myFn);
_
_#myParent
_オブジェクトに汎用jQueryイベントハンドラーをインストールします。クリックイベントがこの委任イベントハンドラーにバブルアップすると、jQueryはこのオブジェクトにアタッチされた委任イベントハンドラーのリストを調べ、イベントの元の要素が委任イベントハンドラーのセレクターのいずれかに一致するかどうかを確認する必要があります。
セレクタはかなり複雑になる可能性があるため、jQueryは各セレクタを解析し、元のイベントターゲットの特性と比較して、各セレクタに一致するかどうかを確認する必要があることを意味します。これは安価な操作ではありません。それらのいずれかが1つだけであれば大したことではありませんが、すべてのセレクターをドキュメントオブジェクトに配置し、すべての単一のバブルイベントと比較するセレクターが何百もある場合、これはイベント処理のパフォーマンスを著しく低下させ始める可能性があります。
このため、デリゲートイベントハンドラーをターゲットオブジェクトにできるだけ近づけるように、デリゲートイベントハンドラーをセットアップする必要があります。つまり、デリゲートされた各イベントハンドラーを介してバブルするイベントが少なくなり、パフォーマンスが向上します。すべてのバブルイベントは、すべての委任イベントハンドラーを通過し、すべての可能な委任イベントセレクターに対して評価される必要があるため、すべての委任イベントをドキュメントオブジェクトに配置することは、最悪のパフォーマンスです。これがまさに.live()
が廃止された理由です。これは.live()
がやったことであり、非常に非効率的であることが判明したためです。
したがって、最適化されたパフォーマンスを実現するには:
イベント委任とは、要素が実際にDOMに存在する前にハンドラーを記述する手法です。この方法には欠点があり、そのような要件がある場合にのみ使用してください。
イベントの委任はいつ使用しますか?
なぜイベントの委任を使用すべきではないのか
PS:動的コンテンツの場合でも、コンテンツがDOMに挿入された後にハンドラーをバインドする場合、イベント委任メソッドを使用する必要はありません。 (動的コンテンツを頻繁に削除/再追加しないで追加する場合)
どうやら、現在、イベントの委任が実際に推奨されています。少なくともバニラJSの場合。
https://gomakethings.com/why-event-delegation-is-a-better-way-to-listen-for-events-in-Vanilla-js/
「Webパフォーマンス#ドキュメントのすべてのクリックを聞くのはパフォーマンスに悪いように感じますが、実際には、個々のアイテムに多数のイベントリスナーを配置するよりもパフォーマンスが高くなります。」