Tous les événements jquery doivent-ils être liés à $ (document)?

D’où cela vient

Lorsque j’ai appris jQuery pour la première fois, je rattachais normalement des événements comme celui-ci:

$('.my-widget a').click(function() { $(this).toggleClass('active'); }); 

Après en savoir plus sur la vitesse du sélecteur et la délégation des événements, j’ai lu à plusieurs endroits que “la délégation d’événement jQuery accélérera votre code”. J’ai donc commencé à écrire du code comme ceci:

 $('.my-widget').on('click','a',function() { $(this).toggleClass('active'); }); 

C’était également la méthode recommandée pour répliquer le comportement de l’événement .live () obsolète. Ce qui est important pour moi car beaucoup de mes sites ajoutent / suppriment dynamicment des widgets tout le temps. Le comportement ci-dessus ne se comporte pas exactement comme .live (), puisque seuls les éléments ajoutés au conteneur ‘.my-widget’ déjà existant auront le comportement. Si j’ajoute dynamicment un autre bloc de HTML après l’exécution de ce code, ces éléments ne seront pas liés aux événements. Comme ça:

 setTimeout(function() { $('body').append(''); }, 1000); 

Ce que je veux réaliser:

  1. l’ancien comportement de .live () // signifiant attacher des événements à des éléments qui n’existaient pas encore
  2. les avantages de .on ()
  3. performance la plus rapide pour lier des événements
  4. Un moyen simple de gérer les événements

Je joins maintenant tous les événements comme ceci:

 $(document).on('click.my-widget-namespace', '.my-widget a', function() { $(this).toggleClass('active'); }); 

Qui semble répondre à tous mes objectives. (Oui, c’est plus lent dans IE pour une raison quelconque, aucune idée de la raison?) C’est rapide car un seul événement est lié à un élément singulier et le sélecteur secondaire est évalué uniquement lorsque l’événement se produit. L’espace de noms est génial, car il facilite la commutation de l’auditeur d’événements.

Ma solution / question

Je commence donc à penser que les événements jQuery doivent 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 meilleure pratique? Si non, pourquoi?

Si vous avez lu tout cela, merci. J’apprécie tout / tous les commentaires / idées.

Hypothèses:

  1. Utiliser jQuery qui supporte .on() // au moins la version 1.7
  2. Vous voulez que l’événement soit ajouté au contenu ajouté dynamicment

Lectures / Exemples:

  1. http://24ways.org/2011/your-jquery-now-with-less-suck
  2. http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery
  3. http://www.jasonbuckboyer.com/playground/speed/speed.html
  4. http://api.jquery.com/on/

Non – vous ne devez PAS lier tous les gestionnaires d’événements delegates à l’object 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 certains cas pas. Vous devez utiliser la délégation d’événement lorsque vous avez réellement besoin d’une délégation d’événement et lorsque vous en bénéficiez. Sinon, vous devez lier les gestionnaires d’événements directement aux objects sur lesquels l’événement se produit car cela sera généralement plus efficace.

Deuxièmement, vous ne devez PAS lier tous les événements delegates au niveau du document. C’est exactement la raison .live() laquelle .live() est obsolète car cela est très inefficace lorsque vous avez beaucoup d’événements liés de cette façon. Pour la gestion des événements delegates, il est BEAUCOUP plus efficace de les lier au parent le plus proche qui n’est pas dynamic.

Troisièmement, tous les événements ne fonctionnent pas ou tous les problèmes peuvent être résolus avec délégation. Par exemple, si vous souhaitez intercepter des événements clés sur un contrôle d’entrée et empêcher que des clés non valides soient entrées dans le contrôle d’entrée, vous ne pouvez pas le faire avec la gestion des événements delegates. été traité par le contrôle d’entrée et qu’il est trop tard pour influencer ce comportement.

Voici les moments où la délégation d’événement est requirejse ou avantageuse:

  • Lorsque les objects sur lesquels vous capturez des événements sont créés / supprimés de manière dynamic et que vous souhaitez toujours capturer des événements sur eux sans avoir à relier explicitement les gestionnaires d’événements à chaque fois que vous en créez un.
  • Lorsque vous avez beaucoup d’objects, tous veulent exactement le même gestionnaire d’événement (où les lots sont au moins des centaines). Dans ce cas, il peut être plus efficace au moment de l’installation de lier un gestionnaire d’événements délégué plutôt que des centaines ou plus de gestionnaires d’événements directs. Remarque: la gestion des événements delegates est toujours moins efficace au moment de l’exécution que les gestionnaires d’événements directs.
  • Lorsque vous essayez de capturer (à un niveau supérieur de votre document) des événements qui se produisent sur un élément du document.
  • Lorsque votre conception utilise explicitement la diffusion d’événements et stopPropagation () pour résoudre certains problèmes ou fonctionnalités de votre page.

Pour mieux comprendre cela, il faut comprendre comment fonctionnent les gestionnaires d’événements delegates jQuery. Lorsque vous appelez quelque chose comme ceci:

 $("#myParent").on('click', 'button.actionButton', myFn); 

Il installe un gestionnaire d’événement jQuery générique sur l’object #myParent . Lorsqu’un événement click se projette sur ce gestionnaire d’événements délégué, jQuery doit parcourir la liste des gestionnaires d’événements delegates attachés à cet object et voir si l’élément d’origine de l’événement correspond à l’un des sélecteurs des gestionnaires d’événements delegates.

Comme les sélecteurs peuvent être assez impliqués, cela signifie que jQuery doit parsingr chaque sélecteur, puis le comparer aux caractéristiques de la cible d’événement d’origine pour voir s’il correspond à chaque sélecteur. Ce n’est pas une opération bon marché. Ce n’est pas grave si il n’y en a qu’un, mais si vous placez tous vos sélecteurs sur l’object de document et qu’il y a des centaines de sélecteurs à comparer à chaque événement, cela peut sérieusement compromettre les performances de gestion des événements.

Pour cette raison, vous souhaitez configurer vos gestionnaires d’événements delegates afin qu’un gestionnaire d’événements délégué soit aussi proche de l’object cible que possible. Cela signifie que moins d’événements seront projetés dans chaque gestionnaire d’événements délégué, améliorant ainsi les performances. Placer tous les événements delegates sur l’object de document est la pire performance possible, car tous les événements doivent passer par tous les gestionnaires d’événements delegates et être évalués par rapport à tous les sélecteurs d’événements delegates possibles. C’est exactement pourquoi .live() est déconseillé car c’est ce que fait .live() et il s’est avéré très inefficace.


Donc, pour obtenir des performances optimisées:

  1. N’utilisez la gestion des événements déléguée que lorsqu’elle fournit une fonctionnalité dont vous avez besoin ou améliore les performances. Ne l’utilisez pas simplement parce que c’est facile parce que vous n’en avez pas vraiment besoin. En fait, le temps d’exécution des événements est plus mauvais que la liaison directe aux événements.
  2. Attachez les gestionnaires d’événements delegates au parent le plus proche de la source de l’événement. Si vous utilisez la gestion des événements delegates car vous avez des éléments dynamics pour lesquels vous souhaitez capturer des événements, sélectionnez le parent le plus proche qui n’est pas lui-même dynamic.
  3. Utilisez des sélecteurs faciles à évaluer pour les gestionnaires d’événements delegates. Si vous avez suivi le fonctionnement de la gestion des événements déléguée, vous comprendrez qu’un gestionnaire d’événements délégué doit être comparé à de nombreux objects afin de sélectionner un sélecteur aussi efficace que possible ou d’append des classes simples à vos objects. augmenter les performances de la gestion des événements delegates.

La délégation d’événement est une technique permettant d’écrire vos gestionnaires avant que l’élément n’existe 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énement?

  1. Lorsque vous liez un gestionnaire commun pour plus d’éléments nécessitant la même fonctionnalité. (Ex: vol stationnaire de la table)
    • Dans l’exemple, si vous deviez lier toutes les lignes à l’aide de la liaison directe, vous créeriez le gestionnaire n pour n lignes dans cette table. En utilisant la méthode de délégation, vous pourriez vous retrouver avec tous les gestionnaires simples.
  2. Lorsque vous ajoutez des contenus dynamics plus fréquemment dans DOM (Ex: Ajouter / supprimer des lignes d’une table)

Pourquoi ne pas utiliser la délégation d’événement?

  1. La délégation d’événements est plus lente par rapport à la liaison directe de l’événement à element.
    • Il compare le sélecteur de cible sur chaque bulle qu’il frappe, la comparaison sera aussi coûteuse que compliquée.
  2. Pas de contrôle sur l’événement en train de bouillir jusqu’à ce qu’il atteigne l’élément auquel il est lié.

PS: Même pour les contenus dynamics, vous n’avez pas besoin d’utiliser la méthode de délégation d’événements si vous associez le gestionnaire après l’insertion du contenu dans DOM. (Si le contenu dynamic est ajouté pas fréquemment supprimé / ajouté)