Je suis en train de comprendre cette différence particulière entre les directs et délégués des gestionnaires d'événements en utilisant le jQuery .on () méthode . Plus précisément, la dernière phrase de ce paragraphe:
Lorsqu'un
selector
est fourni, le gestionnaire d'événements est appelé délégué . Le gestionnaire n'est pas appelé lorsque l'événement se produit directement sur l'élément lié, mais uniquement pour les descendants (éléments internes) qui correspondent au sélecteur. jQuery fait remonter l'événement de la cible de l'événement jusqu'à l'élément auquel le gestionnaire est attaché (c'est-à-dire du plus profond à l'élément le plus externe) et exécute le gestionnaire pour tous les éléments le long de ce chemin correspondant au sélecteur.
Que signifie "exécute le gestionnaire pour tous les éléments"? J'ai fait une page de test pour expérimenter le concept. Mais les deux constructions suivantes conduisent au même comportement:
$("div#target span.green").on("click", function() {
alert($(this).attr("class") + " is clicked");
});
ou,
$("div#target").on("click", "span.green", function() {
alert($(this).attr("class") + " is clicked");
});
Peut-être que quelqu'un pourrait se référer à un exemple différent pour clarifier ce point? Merci.
Réponses:
Cas 1 (direct):
== Hé! Je veux que chaque span.green à l'intérieur de div # target écoute: quand on clique dessus, fais X.
Cas 2 (délégué):
== Hé, div # cible! Quand l'un de vos éléments enfants qui sont "span.green" est cliqué, faites X avec eux.
En d'autres termes...
Dans le cas 1, chacune de ces travées a reçu des instructions individuellement. Si de nouvelles plages sont créées, elles n'auront pas entendu l'instruction et ne répondront pas aux clics. Chaque travée est directement responsable de ses propres événements.
Dans le cas 2, seul le conteneur a reçu l'instruction; il est responsable de la détection des clics au nom de ses éléments enfants. Le travail des événements de capture a été délégué . Cela signifie également que l'instruction sera exécutée pour les éléments enfants qui seront créés à l'avenir.
la source
on()
autorise-t-il deux arguments alors que ce serait à peu près la même chose que l'utilisationclick()
?e.target
sera la cible initiale de l'événement de clic (peut être un nœud enfant s'ilspan.green
a des enfants). Depuis l'intérieur du gestionnaire, vous devez utiliser lathis
référence. Voyez ce violon .La première façon
$("div#target span.green").on()
,, lie un gestionnaire de clic directement à la ou aux plages qui correspondent au sélecteur au moment où le code est exécuté. Cela signifie que si d'autres intervalles sont ajoutés plus tard (ou ont leur classe modifiée pour correspondre), ils ont manqué et n'auront pas de gestionnaire de clics. Cela signifie également que si vous supprimez plus tard la classe "verte" de l'une des plages, son gestionnaire de clics continuera à s'exécuter - jQuery ne garde pas trace de la façon dont le gestionnaire a été affecté et vérifie si le sélecteur correspond toujours.La deuxième façon
$("div#target").on()
,, lie un gestionnaire de clics aux div (s) qui correspondent (encore une fois, c'est contre ceux qui correspondent à ce moment), mais quand un clic se produit quelque part dans le div, la fonction de gestionnaire ne sera exécutée que si le clic s'est produit non seulement dans le div mais dans un élément enfant correspondant au sélecteur du deuxième paramètre à.on()
"span.green". De cette façon, peu importe la date de création de ces intervalles enfants, cliquer dessus exécutera toujours le gestionnaire.Donc, pour une page qui n'ajoute pas ou ne modifie pas dynamiquement son contenu, vous ne remarquerez pas de différence entre les deux méthodes. Si vous ajoutez dynamiquement des éléments enfants supplémentaires, la deuxième syntaxe signifie que vous n'avez pas à vous soucier de leur attribuer des gestionnaires de clics car vous l'avez déjà fait une fois sur le parent.
la source
L'explication de N3dst4 est parfaite. Sur cette base, nous pouvons supposer que tous les éléments enfants sont à l'intérieur du corps, nous n'avons donc besoin que de ceci:
Cela fonctionne avec un événement direct ou délégué.
la source
$('body').on()
délégation de.element
doit se comporter exactement de la même manière que nativedocument.body.addEventHandler()
avec unif (Event.target.className.matches(/\belement\b/))
dans le rappel. Cela peut être très légèrement plus lent dans jquery en raison de la$.proxy
surcharge, mais ne me citez pas là-dessus.Tangentiel à l'OP, mais le concept qui m'a aidé à démêler la confusion avec cette fonctionnalité est que les éléments liés doivent être les parents des éléments sélectionnés .
.on
..on()
.La délégation ne fonctionne pas comme .find (), en sélectionnant un sous-ensemble des éléments liés. Le sélecteur s'applique uniquement aux éléments enfants stricts.
est très différent de
En particulier, pour obtenir les avantages des conseils @ N3dst4 avec les "éléments créés à l'avenir", l'élément lié doit être un parent permanent . Ensuite, les enfants sélectionnés peuvent aller et venir.
ÉDITER
Liste de contrôle des raisons pour lesquelles la délégation
.on
ne fonctionne pasRaisons délicates pour lesquelles
$('.bound').on('event', '.selected', some_function)
peuvent ne pas fonctionner:.on()
.stopPropagation()
.(Omettre des raisons moins délicates, comme un sélecteur mal orthographié.)
la source
J'ai écrit un article avec une comparaison des événements directs et délégués. Je compare js pur mais cela a la même signification pour jquery qui ne fait que l'encapsuler.
La conclusion est que la gestion déléguée des événements est destinée à la structure DOM dynamique où des éléments liés peuvent être créés pendant que l'utilisateur interagit avec la page (plus besoin de liaisons), et la gestion directe des événements est destinée aux éléments DOM statiques, lorsque nous savons que la structure ne changera pas.
Pour plus d'informations et une comparaison complète - http://maciejsikora.com/standard-events-vs-event-delegation/
Utiliser toujours des gestionnaires délégués, ce qui, à mon avis, est actuellement très à la mode n'est pas la bonne manière, de nombreux programmeurs l'utilisent parce que "il devrait être utilisé", mais la vérité est que les gestionnaires d'événements directs sont meilleurs pour certaines situations et le choix de la méthode à utiliser par la connaissance des différences.
la source