Le code est le suivant :
var $test = $(document);
function handler1() {
console.log( "handler1" );
$test.off( "click", handler2 );
}
function handler2() {
console.log( "handler2" );
}
$test.on( "click", handler1 );
$test.on( "click", handler2 );
Pourquoi ce code affiche-t-il handler1 et handler2 lorsqu'il est cliqué pour la première fois ? Le off dans handler1 fonctionne mais handler2 est toujours exécuté une fois. Quelle est la raison ?
Référez-vous à la documentation jQuery
L'explication dans le document est la suivante : l'ajout ou la suppression de gestionnaires d'événements sur l'élément actuel ne prendra effet qu'à la prochaine gestion de l'événement
Peut-être que mon anglais est trop mauvais, j'ai l'impression que l'expression à cet endroit n'est pas très précise , ça devrait être L'ajout ou la suppression du même événement n'est pas valide lors du traitement en cours. Par exemple, j'ai modifié les deux clics comme suit
var $test = $(document);
function handler1() {
console.log( "handler1" );
$test.off( "mouseup", handler2 );
}
function handler2() {
console.log( "handler2" );
}
$test.on( "mousedown", handler1 );
$test.on( "mouseup", handler2 );
Ensuite, seul handler1 sera affiché. On peut voir que la désactivation de mouseup dans mousedown est réussie
.Retour au début, pourquoi l'ajout ou la suppression d'un même événement est invalide lors du traitement en cours ? (J'ai essayé de trouver le code source de jQuery, mais c'était assez compliqué, alors j'ai abandonné)
Il faut quand même partir du code source
Regardez ici d'abord : https://github.com/jquery/jqu...
C'est le début du code de base pour la distribution d'événements.On peut voir que jquery doit appeler this.event.handler pour trouver la liste des rappels d'événements lors de la distribution d'événements Le handlerQueue ici n'est qu'une copie d'une partie. de la liste d'événements interne, et vous utilisez off pour la modifier. Il s'agit d'une liste d'événements interne et n'a aucun effet sur le handlerQueue copié.
C'est comme si toutes les fonctions de rappel d'événement étaient stockées dans le pot. Lorsqu'un événement se produit, jquery copiera un rappel, le placera dans le bol, puis exécutera les fonctions dans le bol dans l'ordre. Ce que vous modifiez en désactivant concerne uniquement la fonction dans le pot, et la fonction dans le bol n'est pas affectée.
Vous pouvez considérer on comme l'ajout d'une méthode de traitement à un tableau de traitement d'événements du composant, et off comme la suppression de cette méthode du tableau. Lorsqu'un événement est déclenché, jq exécutera immédiatement les méthodes du tableau de traitement d'événements. Alors, que se passe-t-il si off est appelé dans la méthode de traitement d'événements ? Le document a clairement indiqué que la méthode de traitement ne sera pas immédiatement supprimée du tableau dans la boucle de déclenchement de l'événement en cours. Elle ne sera reflétée que lorsque l'événement lié sera à nouveau déclenché.
Merci à tous
Le problème a été trouvé. La raison est que lorsque jq encapsule en interne des événements, les événements du même type seront ajoutés au même tableau, et lorsque l'événement est déclenché, le parcours est une copie de ce tableau. Off ne modifie pas la copie, donc Hanler2 est affiché lorsque vous cliquez pour la première fois. Quant à mousedown et mouseup, car ce sont des types d'événements différents, ils sont encapsulés dans deux tableaux, il est donc efficace de désactiver mouseup dans. souris vers le bas. Peut-être que l'expression n'est pas très bonne, veuillez poster quelques lignes du code source principal de jq