10

En lisant une autre question sur les performances de jQuery, j'ai commencé à réfléchir au moment où il vaut la peine d'utiliser la délégation d'événements plutôt que de lier des éléments individuellement. Je pensais principalement à jQuery, mais je suppose que c'est probablement applicable pour Javascript en général.Combien d'éléments faut-il pour que la délégation d'événements en vaille la peine?

délégation de l'événement a deux objectifs principaux:

  1. permettant des gestionnaires de travailler sur des éléments qui n'ont pas encore été créés/insérés dans les DOM.
  2. liant une fonction à un élément ancêtre commun plutôt que de multiples éléments frères

Ma question concerne la seconde de celles-ci. La réponse générale sera probablement «cela dépend de la situation exacte», mais je me demande s'il existe une règle empirique ou une méthode d'analyse comparative pour tester cela.

Donc, la question est: combien d'éléments avez-vous besoin avant que les avantages de performance de la délégation d'événements l'emportent sur les coûts de performance?

+0

Je ne connaître les coûts de performance de la délégation d'événements ... De quoi s'agit-il? Les événements éclatent quand même et la cible de l'événement est stockée dans la propriété correspondante de l'objet événement à tout moment. –

+1

@Sime Le principal auquel j'avais pensé était que chaque fois qu'un événement est déclenché, le sélecteur de l'appel de délégué doit être exécuté pour vérifier s'il correspond à la cible de l'événement. Il peut y en avoir d'autres ... – lonesomeday

+2

Considérons que lorsque vous utilisez la délégation, vous répartissez efficacement le coût des gestionnaires de liaison sur la durée de vie de la page. Lorsque vous liez en recherchant les éléments en premier, vous ajoutez plus de travail au moment du chargement de la page, lorsque les utilisateurs sont les plus sensibles aux retards. – Pointy

Répondre

3

En supposant que cette structure HTML:

<ul id="navUL"> 
    <li><a href="one.html">One</a></li> 
    <li><a href="two.html">Two</a></li> 
    <li><a href="three.html">Three</a></li> 
</ul> 

Juste pour clarifier les choses (pour moi) .... Selon docs jQuery (http://api.jquery.com/delegate/), ceci:

$("#navUL").delegate("a", "click", function(){ 
    // anchor clicked 
}); 

... est équivalent à ceci:

$("#navUL").each(function(){ 
    $("a", this).live("click", function(){ 
     // anchor clicked 
    }); 
}); 

Cependant, la délégation de l'événement (comme je le sais) est la suivante:

$("#navUL").click(function(e) { 
    if (e.target.nodeName !== "A") { return false; } 
    // anchor clicked 
    // anchor is referenced by e.target 
}); 

Vous attraper l'événement, cliquez sur l'élément UL, puis la figure sur laquelle l'ancre a été effectivement cliqué via la propriété event.target.

Je ne sais pas sur la méthode délégué(), mais cette dernière technique devrait toujours être plus rapide que la fixation des gestionnaires d'événements à chaque point d'ancrage dans l'élément #navUL, comme ceci:

$("#navUL a").click(function() { 
    // anchor clicked 
    // anchor is referenced by the this value 
}); 
+0

N'avez-vous pas besoin d'un 'e.stopPropagation();' dans votre délégation comme vous le savez par exemple? –

+0

Hm, pourquoi? L'utilisateur clique quelque part dans l'élément #navUL. L'événement click se propage à l'élément #navUL (puisqu'il n'y a aucun gestionnaire de clic attaché aux éléments A ou LI). Dans le gestionnaire de clics #navUL, je vérifie si une ancre a été cliquée. Sinon, je viens de tuer l'événement (via return false;). Si oui, je fais ce que je voulais (avec l'ancre). Je peux vouloir empêcher le comportement par défaut de l'ancre, mais je ne vois pas pourquoi je voudrais empêcher l'événement de clic de bouillir l'arbre de DOM (je n'ai aucun gestionnaire de clic réglé sur les éléments d'ancêtre, de toute façon). –

+0

Oui, vous avez raison. –