Lorsque j'ai appris jQuery pour la première fois, j’attachais normalement des événements comme celui-ci:
$('.my-widget a').click(function() {
$(this).toggleClass('active');
});
Après en savoir plus sur la vitesse de sélection et la délégation d'événements, j'ai lu à plusieurs reprises que "la délégation d'événements jQuery rendra votre code plus rapide". Alors j'ai commencé à écrire du code comme ceci:
$('.my-widget').on('click','a',function() {
$(this).toggleClass('active');
});
C'était également le moyen recommandé de répliquer le comportement de l'événement obsolète .live (). Ce qui est important pour moi, car bon nombre de mes sites ajoutent/suppriment dynamiquement des widgets tout le temps. Ce qui précède ne se comporte cependant pas exactement comme .live (), car seuls les éléments ajoutés au conteneur existant. 'Mon-widget' auront le comportement. Si j'ajoute dynamiquement un autre bloc de code html une fois le code exécuté, ces événements ne seront pas associés aux événements. Comme ça:
setTimeout(function() {
$('body').append('<div class="my-widget"><a>Click does nothing</a></div>');
}, 1000);
J'attache maintenant tous les événements comme celui-ci:
$(document).on('click.my-widget-namespace', '.my-widget a', function() {
$(this).toggleClass('active');
});
Ce qui semble répondre à tous mes objectifs. (Oui, c'est plus lent dans IE pour une raison quelconque, aucune idée de pourquoi?) C'est rapide, car un seul événement est lié à un élément singulier et le sélecteur secondaire n'est évalué que lorsque l'événement se produit (veuillez corrigez-moi si cela est faux ici). L'espace de noms est génial puisqu'il facilite le basculement de l'écouteur d'événements.
Je commence donc à penser que les événements jQuery devraient toujours être liés à $ (document).
Y a-t-il une raison pour laquelle vous ne voudriez pas faire cela?
Cela pourrait-il être considéré comme une pratique exemplaire? Si non, pourquoi?
Si vous avez tout lu, merci. J'apprécie tout/tous les commentaires/idées.
Hypothèses:
.on()
// au moins la version 1.7Lectures/Exemples:
Non - vous ne devez PAS lier tous les gestionnaires d'événements délégués à l'objet document
. C'est probablement le pire scénario que vous puissiez créer.
Tout d'abord, la délégation d'événements ne rend pas toujours votre code plus rapide. Dans certains cas, c'est avantageux et dans d'autres, non. Vous devez utiliser la délégation d'événements lorsque vous en avez réellement besoin et lorsque vous en bénéficiez. Sinon, vous devez lier les gestionnaires d'événements directement aux objets sur lesquels l'événement se produit, ce qui sera généralement plus efficace.
Deuxièmement, vous ne devriez PAS lier tous les événements délégués au niveau du document. C’est exactement pour cette raison que .live()
est déconseillé car c’est très inefficace lorsque de nombreux événements sont liés de cette façon. Pour la gestion des événements délégués, il est BEAUCOUP plus efficace de les lier au parent le plus proche qui n’est pas dynamique.
Troisièmement, tous les événements ne fonctionnent pas et tous les problèmes ne peuvent pas être résolus par délégation. Par exemple, si vous souhaitez intercepter des événements clés sur un contrôle de saisie et empêcher la saisie de clés non valides dans le contrôle de saisie, vous ne pouvez pas le faire avec la gestion des événements délégués car, au moment où l'événement se propage jusqu'au gestionnaire délégué, il a déjà été traité par le contrôle d’entrée et il est trop tard pour influencer ce comportement.
Voici des moments où la délégation d'événements est requise ou avantageuse:
Pour comprendre cela un peu plus, il faut comprendre le fonctionnement des gestionnaires d'événements délégués de jQuery. Lorsque vous appelez quelque chose comme ceci:
$("#myParent").on('click', 'button.actionButton', myFn);
Il installe un gestionnaire d'événements générique jQuery sur l'objet #myParent
. Lorsqu'un événement click clique sur ce gestionnaire d'événements délégué, jQuery doit parcourir la liste des gestionnaires d'événements délégués attachés à cet objet et voir si l'élément d'origine de l'événement correspond à l'un des sélecteurs des gestionnaires d'événements délégués.
Les sélecteurs pouvant être relativement impliqués, cela signifie que jQuery doit analyser chaque sélecteur, puis le comparer aux caractéristiques de la cible de l'événement d'origine pour voir si elle correspond à chaque sélecteur. Ce n'est pas une opération bon marché. Ce n'est pas grave s'il n'y en a qu'un, mais si vous placez tous vos sélecteurs sur l'objet document et que vous devez comparer des centaines de sélecteurs à chaque événement diffusé, cela peut sérieusement entraver les performances de gestion des événements.
Pour cette raison, vous souhaitez configurer vos gestionnaires d'événements délégués de manière à ce qu'un gestionnaire d'événements délégué soit aussi proche de l'objet cible que possible. Cela signifie que moins d’événements apparaîtront dans chaque gestionnaire d’événements délégué, améliorant ainsi les performances. Placer tous les événements délégués sur l'objet document est la pire performance possible, car tous les événements condensés doivent passer par tous les gestionnaires d'événements délégués et être évalués par rapport à tous les sélecteurs d'événements délégués possibles. C’est exactement pourquoi .live()
est obsolète, car c’est ce que .live()
a fait et cela s’est avéré très inefficace.
Donc, pour obtenir des performances optimisées:
La délégation d'événements est une technique permettant d'écrire vos gestionnaires avant que l'élément n'existe réellement dans DOM. Cette méthode a ses propres inconvénients et ne devrait être utilisée que si vous avez de telles exigences.
Quand devriez-vous utiliser la délégation d'événements?
Pourquoi ne devriez-vous pas utiliser la délégation d'événements?
PS: Même pour les contenus dynamiques, il n'est pas nécessaire d'utiliser la méthode de délégation d'événements si vous liez le gestionnaire une fois le contenu inséré dans DOM. (Si le contenu dynamique est ajouté pas fréquemment supprimé/ré-ajouté)
Apparemment, la délégation d'événements est actuellement recommandée. au moins pour Vanilla js.
https://gomakethings.com/why-event-delegation-is-a-better-way-to-listen-for-events-in-Vanilla-js/
"Performances Web # C’est comme si écouter chaque clic du document était mauvais pour la performance, mais c’est plus performant que d’avoir un groupe d’écouteurs d’événements sur des éléments individuels."