jfriend00の回答にいくつかの発言と反論を追加したいと思います。(ほとんどが私の感覚に基づいた私の意見です)
いいえ - すべての委任されたイベント ハンドラーをドキュメント オブジェクトにバインドしないでください。これはおそらく、作成できる最悪のシナリオです。
まず、イベント委譲によって常にコードが高速化されるわけではありません。有利な場合もあれば、不利な場合もあります。実際にイベントの委任が必要な場合、およびそれによってメリットがある場合は、イベントの委任を使用する必要があります。それ以外の場合は、イベントが発生するオブジェクトにイベント ハンドラーを直接バインドする必要があります。これにより、通常はより効率的になります。
1 つの要素に対してのみ登録してイベントを実行する場合にパフォーマンスがわずかに向上する可能性があることは事実ですが、委任によってもたらされるスケーラビリティの利点に比べれば、それほど重要ではないと思います。また、ブラウザはこれをますます効率的に処理していると思いますが、これを証明するものはありません。私の意見では、イベント委任が最適です。
次に、委任されたすべてのイベントをドキュメント レベルでバインドしないでください。.live() が廃止されたのはまさにこのためです。これは、多くのイベントがこの方法でバインドされている場合に非常に非効率的であるためです。委任されたイベント処理の場合、それらを動的ではない最も近い親にバインドする方がはるかに効率的です。
私はこれに同意します。イベントがコンテナー内でのみ発生することが 100% 確実な場合は、イベントをこのコンテナーにバインドすることは理にかなっていますが、イベントをトリガー要素に直接バインドすることには反対です。
第三に、すべてのイベントが機能するわけではなく、すべての問題が委任によって解決できるわけではありません。たとえば、入力コントロールのキー イベントをインターセプトし、無効なキーが入力コントロールに入力されるのをブロックする場合、イベントが委任されたハンドラーに到達するまでに、イベントが既に処理されているため、委任されたイベント処理ではそれを行うことができません。入力コントロールによって処理されており、その動作に影響を与えるには遅すぎます。
これは単に真実ではありません。このコードペンを参照してください: https://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
ドキュメントに keypress イベントを登録することで、ユーザーが入力できないようにする方法を示しています。
イベントの委任が必要な場合、または有利な場合は次のとおりです。
イベントをキャプチャしているオブジェクトが動的に作成/削除され、新しいオブジェクトを作成するたびにイベント ハンドラーを明示的に再バインドすることなくそれらのイベントをキャプチャしたい場合。すべてがまったく同じイベント ハンドラーを必要とするオブジェクトが多数ある場合 (ロットは少なくとも数百です)。この場合、セットアップ時に、100 以上の直接イベント ハンドラーよりも、1 つの委任されたイベント ハンドラーをバインドする方が効率的である可能性があります。委任されたイベント処理は、直接のイベント ハンドラーよりも実行時の効率が常に低いことに注意してください。
https://ehsangazar.com/optimizing-javascript-event-listeners-for-performance-e28406ad406cからのこの引用で返信したいと思います
Event delegation promotes binding as few DOM event handlers as possible, since each event handler requires memory. For example, let’s say that we have an HTML unordered list we want to bind event handlers to. Instead of binding a click event handler for each list item (which may be hundreds for all we know), we bind one click handler to the parent unordered list itself.
また、グーグルでperformance cost of event delegation google
検索すると、イベント委任を支持するより多くの結果が返されます。
ドキュメント内の任意の要素で発生するイベントを (ドキュメント内のより高いレベルで) キャプチャしようとしている場合。デザインで明示的にイベント バブリングと stopPropagation() を使用して、ページの問題または機能を解決する場合。これをもう少し理解するには、jQuery の委任されたイベント ハンドラーがどのように機能するかを理解する必要があります。次のようなものを呼び出すと:
$("#myParent").on('クリック', 'button.actionButton', myFn); #myParent オブジェクトに一般的な jQuery イベント ハンドラーをインストールします。クリック イベントがこの委任されたイベント ハンドラーに到達すると、jQuery は、このオブジェクトに関連付けられた委任されたイベント ハンドラーのリストを調べて、イベントの元の要素が委任されたイベント ハンドラーのいずれかのセレクターと一致するかどうかを確認する必要があります。
セレクターはかなり関与する可能性があるため、jQuery は各セレクターを解析し、それを元のイベント ターゲットの特性と比較して、各セレクターと一致するかどうかを確認する必要があります。これは安価な操作ではありません。それらが 1 つしかない場合は大したことではありませんが、ドキュメント オブジェクトにすべてのセレクターを配置し、バブルされたすべてのイベントと比較するセレクターが何百もある場合、イベント処理のパフォーマンスが著しく低下する可能性があります。
このため、委任されたイベント ハンドラーをセットアップして、委任されたイベント ハンドラーが実際にターゲット オブジェクトの近くに配置されるようにします。これは、委任された各イベント ハンドラーを通過するイベントが少なくなるため、パフォーマンスが向上することを意味します。委任されたすべてのイベントをドキュメント オブジェクトに配置すると、パフォーマンスが最悪になります。これは、バブリングされたすべてのイベントがすべての委任されたイベント ハンドラーを通過し、すべての委任されたイベント セレクターに対して評価される必要があるためです。これがまさに .live() が廃止された理由です。これは .live() が行ったことであり、非常に非効率的であることが判明したためです。
これはどこに文書化されていますか? それが本当なら、jQuery は非常に非効率的な方法で委譲を処理しているようであり、私の反論はバニラ JS にのみ適用されるべきです。
それでも:この主張を裏付ける公式の情報源を見つけたい.
:: 編集 ::
jQueryは実際に非常に非効率的な方法でイベントバブリングを行っているようです(IE8をサポートしているため)
https://api.jquery.com/on/#event-performance
したがって、ここでの私の議論のほとんどは、標準の JS と最新のブラウザーにのみ当てはまります。