Disons que j'ai une application Web qui a une page qui peut contenir 4 blocs de script - le script que j'écris peut être trouvé dans l'un de ces blocs, mais je ne sais pas lequel, qui est géré par le contrôleur.
Je lie certains onclick
événements à un bouton, mais je trouve qu'ils s'exécutent parfois dans un ordre auquel je ne m'attendais pas.
Existe-t-il un moyen de garantir l'ordre ou comment avez-vous géré ce problème dans le passé?
javascript
jquery
events
mkoryak
la source
la source
Réponses:
J'essayais depuis des lustres de généraliser ce genre de processus, mais dans mon cas, je n'étais préoccupé que par l'ordre du premier auditeur d'événements de la chaîne.
Si cela est utile, voici mon plugin jQuery qui lie un écouteur d'événement qui est toujours déclenché avant les autres:
** MISE À JOUR en ligne avec les changements de jQuery (merci Toskan) **
Choses à noter:
la source
this.data("events")
, voir ici stackoverflow.com/questions/12214654Si l'ordre est important, vous pouvez créer vos propres événements et lier les rappels pour qu'ils se déclenchent lorsque ces événements sont déclenchés par d'autres rappels.
Quelque chose comme ça au moins.
la source
La méthode de Dowski est bonne si tous vos rappels sont toujours présents et que vous êtes satisfait qu'ils soient dépendants les uns des autres.
Cependant, si vous souhaitez que les rappels soient indépendants les uns des autres, vous pouvez profiter de la création de bulles et attacher des événements ultérieurs en tant que délégués aux éléments parents. Les gestionnaires d'un élément parent seront déclenchés après les gestionnaires de l'élément, en continuant jusqu'au document. Ceci est tout à fait bon que vous pouvez utiliser
event.stopPropagation()
,event.preventDefault()
etc pour sauter les gestionnaires et annuler ou non annuler l'action.Ou, si vous n'aimez pas cela, vous pouvez utiliser le plugin Nick Leaches bindLast pour forcer un événement à être lié en dernier: https://github.com/nickyleach/jQuery.bindLast .
Ou, si vous utilisez jQuery 1.5, vous pouvez également faire quelque chose d'intelligent avec le nouvel objet Deferred.
la source
.delegate
n'est plus utilisé et vous devriez maintenant l'utiliser.on
, mais je ne sais pas comment vous pouvez atteindre le même comportement avecon
L'ordre dans lequel les rappels liés sont appelés est géré par les données d'événement de chaque objet jQuery. Il n'y a pas de fonctions (que je connaisse) qui vous permettent de visualiser et de manipuler ces données directement, vous ne pouvez utiliser que bind () et unbind () (ou l'une des fonctions d'assistance équivalentes).
La méthode de Dowski est la meilleure, vous devez modifier les divers rappels liés pour les lier à une séquence ordonnée d'événements personnalisés, avec le "premier" rappel lié à l'événement "réel". De cette façon, quel que soit l'ordre dans lequel ils sont liés, la séquence s'exécutera de la bonne manière.
La seule alternative que je peux voir est quelque chose que vous ne voulez vraiment, vraiment pas envisager: si vous connaissez la syntaxe de liaison des fonctions peut avoir été liée avant vous, essayez de dissocier toutes ces fonctions, puis de les relier à nouveau dans le bon ordre vous-même. Cela pose juste des problèmes, car maintenant vous avez du code en double.
Ce serait cool si jQuery vous permettait de changer simplement l'ordre des événements liés dans les données d'événement d'un objet, mais sans écrire du code à accrocher dans le noyau jQuery, ce qui ne semble pas possible. Et il y a probablement des implications à autoriser cela auxquelles je n'ai pas pensé, alors peut-être que c'est une omission intentionnelle.
la source
Veuillez noter que dans l'univers jQuery, cela doit être implémenté différemment à partir de la version 1.8. La note de publication suivante est tirée du blog jQuery:
Nous avons un contrôle complet sur l'ordre dans lequel les gestionnaires s'exécuteront dans l'univers jQuery . Ricoo le souligne ci-dessus. Il ne semble pas que sa réponse lui ait valu beaucoup d'amour, mais cette technique est très pratique. Considérez, par exemple, chaque fois que vous devez exécuter votre propre gestionnaire avant un gestionnaire dans un widget de bibliothèque, ou vous devez avoir le pouvoir d'annuler l'appel au gestionnaire du widget de manière conditionnelle:
la source
la source
liez simplement le gestionnaire normalement, puis exécutez:
donc par exemple:
la source
$._data(element, 'events')[name].reverse()
fonctionneVous pouvez essayer quelque chose comme ceci:
la source
J'ai le même problème et j'ai trouvé ce sujet. les réponses ci-dessus peuvent résoudre ces problèmes, mais je ne pense pas que ce soient de bons plans.
pensons au monde réel.
si nous utilisons ces réponses, nous devons changer notre code. vous devez changer votre style de code. quelque chose comme ça:
original:
pirater:
au fil du temps, pensez à votre projet. le code est moche et difficile à lire! la raison est simple, c'est toujours mieux. si vous avez 10 bindAtTheStart, il se peut qu'il n'y ait pas de bogues. si vous avez 100 bindAtTheStart, êtes-vous vraiment sûr de pouvoir les conserver dans le bon ordre?
Donc, si vous devez lier plusieurs événements, je pense que le meilleur moyen est de contrôler l'ordre de chargement du fichier js ou du code js. jquery peut gérer les données d'événement en tant que file d'attente. l'ordre est le premier entré, premier sorti. vous n'avez pas besoin de changer de code. changez simplement l'ordre de chargement.
la source
Voici ma photo, couvrant différentes versions de jQuery:
la source
Dans certains cas particuliers, lorsque vous ne pouvez pas modifier la façon dont les événements de clic sont liés (les liaisons d'événements sont faites à partir des codes des autres), et que vous pouvez modifier l'élément HTML, voici une solution possible ( avertissement : ce n'est pas la manière recommandée de lier événements, d'autres développeurs peuvent vous assassiner pour cela):
Avec cette méthode de liaison, votre gestionnaire d'événement sera ajouté en premier, il sera donc exécuté en premier.
la source
JQuery 1.5 introduit des promesses, et voici l'implémentation la plus simple que j'ai vue pour contrôler l'ordre d'exécution. Documentation complète sur http://api.jquery.com/jquery.when/
la source