jfriend00の回答にいくつかのコメントと反論を追加したいと思います。(主に私の直感に基づく私の意見)
いいえ-すべての委任されたイベントハンドラーをドキュメントオブジェクトにバインドしないでください。それはおそらく、作成できる最悪のシナリオです。
まず、イベントの委任によってコードが高速になるとは限りません。有利な場合もあれば、そうでない場合もあります。イベントの委任が実際に必要な場合、およびその恩恵を受ける場合は、イベントの委任を使用する必要があります。それ以外の場合は、イベントハンドラーを、イベントが発生するオブジェクトに直接バインドする必要があります。これは、一般的に効率的であるためです。
単一の要素を登録してイベントを発生させるだけの場合、パフォーマンスが少し向上する可能性があることは事実ですが、委任によってもたらされるスケーラビリティーの利点と比較して、それが重くなることはないと思います。私はまた、これを証明するものはありませんが、ブラウザがこれをますます効率的に処理していると考えています。私の意見では、イベントの委任は行くべき道です!
次に、委任されたすべてのイベントをドキュメントレベルでバインドしないでください。これがまさに.live()が廃止された理由です。この方法でバインドされた多くのイベントがある場合、これは非常に非効率的です。委任されたイベント処理では、動的ではない最も近い親にそれらをバインドする方がはるかに効率的です。
私はこれにある程度同意します。イベントがコンテナー内でのみ発生することを100%確信している場合は、イベントをこのコンテナーにバインドすることは理にかなっていますが、イベントをトリガー要素に直接バインドすることはまだ反対です。
第三に、すべてのイベントが機能するわけではなく、すべての問題が委任で解決できるわけではありません。たとえば、入力コントロールのキーイベントをインターセプトして、無効なキーが入力コントロールに入力されないようにブロックする場合は、委任されたイベント処理でそれを行うことはできません。これは、イベントが委任されたハンドラーにバブルアップするまでに、入力コントロールによって処理されましたが、その動作に影響を与えるには遅すぎます。
これは単に真実ではありません。このcodePenを参照してください:https ://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
これは、ドキュメントにkeypressイベントを登録することで、ユーザーが入力できないようにする方法を示しています。
以下は、イベントの委任が必要または有利な場合です。
イベントをキャプチャしているオブジェクトが動的に作成または削除され、新しいイベントハンドラを作成するたびにイベントハンドラを明示的に再バインドする必要なしに、それらのイベントをキャプチャしたい場合。まったく同じイベントハンドラーが必要なオブジェクトがたくさんある場合(たくさんは少なくとも数百)。この場合、数百以上の直接イベントハンドラーをバインドするよりも、委任された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( 'click'、 'button.actionButton'、myFn); #myParentオブジェクトに汎用jQueryイベントハンドラーをインストールします。クリックイベントがこの委任されたイベントハンドラーに達すると、jQueryはこのオブジェクトにアタッチされた委任されたイベントハンドラーのリストを調べ、イベントの元の要素が委任されたイベントハンドラーのセレクターのいずれかに一致するかどうかを確認する必要があります。
セレクターはかなり複雑な場合があるため、jQueryは各セレクターを解析し、それを元のイベントターゲットの特性と比較して、各セレクターに一致するかどうかを確認する必要があります。これは安価な操作ではありません。それらが1つしかない場合でも大した問題ではありませんが、すべてのセレクターをドキュメントオブジェクトに配置し、すべての単一のバブルイベントと比較するセレクターが数百ある場合、イベント処理のパフォーマンスが大幅に低下する可能性があります。
このため、委任されたイベントハンドラーをターゲットオブジェクトにできるだけ近づけるように委任されたイベントハンドラーを設定する必要があります。つまり、委任されたイベントハンドラーを介してバブルするイベントが少なくなり、パフォーマンスが向上します。すべての委任されたイベントをドキュメントオブジェクトに配置すると、すべてのバブルイベントがすべての委任されたイベントハンドラーを通過し、すべての可能な委任されたイベントセレクターに対して評価されるため、パフォーマンスが最悪になります。これがまさに.live()が廃止された理由です。これは.live()が行ったことであり、非常に非効率的であることが判明したためです。
これはどこに文書化されていますか?それが本当である場合、jQueryは非常に非効率的な方法で委任を処理しているようであり、その場合、私の反論はバニラJSにのみ適用する必要があります。
それでも:この主張を裏付ける公式の情報源を見つけたいのですが。
::編集::
jQueryは確かに非常に非効率的な方法でイベントバブリングを行っているようです(IE8をサポートしているため)
https://api.jquery.com/on/#event-performance
したがって、ここでの私の議論のほとんどは、バニラJSと最新のブラウザにのみ当てはまります。