Ich möchte der Antwort von jfriend00 einige Bemerkungen und Gegenargumente hinzufügen. (meistens nur meine Meinung basierend auf meinem Bauchgefühl)
Nein - Sie sollten NICHT alle delegierten Ereignishandler an das Dokumentobjekt binden. Dies ist wahrscheinlich das Szenario mit der schlechtesten Leistung, das Sie erstellen können.
Zunächst einmal beschleunigt die Ereignisdelegierung Ihren Code nicht immer. In einigen Fällen ist dies vorteilhaft und in einigen Fällen nicht. Sie sollten die Ereignisdelegierung verwenden, wenn Sie tatsächlich eine Ereignisdelegierung benötigen und wenn Sie davon profitieren. Andernfalls sollten Sie Ereignishandler direkt an die Objekte binden, in denen das Ereignis auftritt, da dies im Allgemeinen effizienter ist.
Zwar ist die Leistung möglicherweise etwas besser, wenn Sie sich nur für ein einzelnes Element registrieren und ein Ereignis durchführen. Ich glaube jedoch, dass dies nicht die Skalierbarkeitsvorteile der Delegierung beeinträchtigt. Ich glaube auch, dass Browser dies immer effizienter handhaben (werden), obwohl ich keinen Beweis dafür habe. Meiner Meinung nach ist Eventdelegation der richtige Weg!
Zweitens sollten Sie NICHT alle delegierten Ereignisse auf Dokumentebene binden. Genau aus diesem Grund wurde .live () nicht mehr unterstützt, da dies sehr ineffizient ist, wenn viele Ereignisse auf diese Weise gebunden sind. Für die Behandlung delegierter Ereignisse ist es VIEL effizienter, sie an das nächste übergeordnete Element zu binden, das nicht dynamisch ist.
Ich stimme dem irgendwie zu. Wenn Sie zu 100% sicher sind, dass ein Ereignis nur innerhalb eines Containers auftritt, ist es sinnvoll, das Ereignis an diesen Container zu binden, aber ich würde trotzdem dagegen sprechen, Ereignisse direkt an das auslösende Element zu binden.
Drittens funktionieren nicht alle Ereignisse oder alle Probleme können mit der Delegierung gelöst werden. Wenn Sie beispielsweise Schlüsselereignisse auf einem Eingabesteuerelement abfangen und die Eingabe ungültiger Schlüssel in das Eingabesteuerelement blockieren möchten, können Sie dies nicht mit der Behandlung delegierter Ereignisse tun, da dies bereits der Fall ist, wenn das Ereignis an den delegierten Handler weitergeleitet wird wurde von der Eingabesteuerung verarbeitet und es ist zu spät, um dieses Verhalten zu beeinflussen.
Das ist einfach nicht wahr. Bitte beachten Sie diesen CodePen: https://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
Es zeigt, wie Sie verhindern können, dass ein Benutzer tippt, indem Sie das Tastendruckereignis im Dokument registrieren.
Hier sind Zeiten, in denen eine Ereignisdelegierung erforderlich oder vorteilhaft ist:
Wenn die Objekte, für die Sie Ereignisse erfassen, dynamisch erstellt / entfernt werden und Sie dennoch Ereignisse erfassen möchten, ohne die Ereignishandler jedes Mal, wenn Sie ein neues erstellen, explizit neu binden zu müssen. Wenn Sie viele Objekte haben, die alle genau den gleichen Ereignishandler benötigen (wobei die Anzahl mindestens Hunderte beträgt). In diesem Fall kann es zur Einrichtungszeit effizienter sein, einen delegierten Ereignishandler zu binden, als Hunderte oder mehr direkte Ereignishandler. Beachten Sie, dass die Behandlung delegierter Ereignisse zur Laufzeit immer weniger effizient ist als direkte Ereignishandler.
Ich möchte mit diesem Zitat von https://ehsangazar.com/optimizing-javascript-event-listeners-for-performance-e28406ad406c antworten
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.
Wenn Sie nach googeln suchen, erhalten Sie performance cost of event delegation google
mehr Ergebnisse zugunsten der Ereignisdelegierung.
Wenn Sie versuchen, Ereignisse (auf einer höheren Ebene in Ihrem Dokument) zu erfassen, die an einem beliebigen Element im Dokument auftreten. Wenn Ihr Design explizit Ereignisblasen und stopPropagation () verwendet, um ein Problem oder eine Funktion auf Ihrer Seite zu lösen. Um dies ein wenig besser zu verstehen, muss man verstehen, wie von jQuery delegierte Ereignishandler funktionieren. Wenn Sie so etwas nennen:
$ ("# myParent"). on ('click', 'button.actionButton', myFn); Es installiert einen generischen jQuery-Ereignishandler für das Objekt #myParent. Wenn ein Klickereignis zu diesem delegierten Ereignishandler sprudelt, muss jQuery die Liste der an dieses Objekt angehängten delegierten Ereignishandler durchgehen und prüfen, ob das Ursprungselement für das Ereignis mit einem der Selektoren in den delegierten Ereignishandlern übereinstimmt.
Da Selektoren ziemlich involviert sein können, bedeutet dies, dass jQuery jeden Selektor analysieren und dann mit den Merkmalen des ursprünglichen Ereignisziels vergleichen muss, um festzustellen, ob er mit jedem Selektor übereinstimmt. Dies ist keine billige Operation. Es ist keine große Sache, wenn es nur eine davon gibt. Wenn Sie jedoch alle Ihre Selektoren auf das Dokumentobjekt setzen und Hunderte von Selektoren mit jedem einzelnen Bubble-Ereignis zu vergleichen waren, kann dies die Leistung der Ereignisbehandlung ernsthaft beeinträchtigen.
Aus diesem Grund möchten Sie Ihre delegierten Ereignishandler so einrichten, dass sich ein delegierter Ereignishandler so nah wie möglich am Zielobjekt befindet. Dies bedeutet, dass weniger Ereignisse durch jeden delegierten Ereignishandler sprudeln und somit die Leistung verbessern. Das Platzieren aller delegierten Ereignisse auf dem Dokumentobjekt ist die schlechteste Leistung, da alle Bubble-Ereignisse alle delegierten Ereignishandler durchlaufen und gegen alle möglichen delegierten Ereignisselektoren ausgewertet werden müssen. Dies ist genau der Grund, warum .live () veraltet ist, weil .live () dies getan hat und sich als sehr ineffizient erwiesen hat.
Wo ist das dokumentiert? Wenn das stimmt, scheint jQuery die Delegierung sehr ineffizient zu behandeln, und dann sollten meine Gegenargumente nur auf Vanilla JS angewendet werden.
Dennoch: Ich würde gerne eine offizielle Quelle finden, die diese Behauptung stützt.
:: EDIT ::
Scheint, als würde jQuery tatsächlich Ereignisblasen auf sehr ineffiziente Weise ausführen (da sie IE8 unterstützen).
Https://api.jquery.com/on/#event-performance
Die meisten meiner Argumente hier gelten also nur für Vanilla JS und moderne Browser.