web-dev-qa-db-fra.com

jQuery .on (); vs JavaScript .addEventListener ();

Quelqu'un peut-il m'expliquer pourquoi existe-t-il une différence dans l'ordre dans lequel les gestionnaires d'événements sont exécutés selon la façon dont ils ont été attachés? Dans l'exemple ci-dessous, j'utilise les méthodes .on() et .addEventListener() pour gérer un événement spécifique sur différents éléments DOM.

jsfiddle : http://jsfiddle.net/etsS2/

J'ai pensé que dans cet exemple particulier, l'ordre dans lequel les gestionnaires d'événements vont être exécutés dépendra du event-bubbling - donc en partant de l'événement d'origine target et en remontant vers le document élément.

document.getElementById('outer').addEventListener('mouseup', function (event) {
//$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

Si je décommente la version de on(); tout fonctionne comme prévu - y a-t-il une différence dans la façon dont jQuery gère les événements contrairement à plain JavaScript?

36
MonkeyCoder

Lorsque vous utilisez .on() au niveau du document, vous attendez que l'événement bouillonne jusqu'à ce point. Le gestionnaire d'événements pour tout conteneur intermédiaire aura déjà été appelé.

L'événement "bouillonnement" est le processus par lequel le navigateur recherche les gestionnaires d'événements enregistrés auprès des parents de l'élément qui était le destinataire d'origine de l'événement. Cela fonctionne vers le haut dans l'arborescence DOM. Le niveau du document est le dernier niveau vérifié. Ainsi, votre gestionnaire enregistré avec .on() ne fonctionnera pas tant que ce niveau n'est pas atteint. En attendant, l'autre gestionnaire d'événements au niveau "externe" est atteint en premier et il est exécuté par le navigateur.

Ainsi, ce return false; Dans le gestionnaire enregistré avec .on() est à peu près inutile, comme ce serait un appel à event.stopPropagation(). Au-delà de cela, mélanger l'enregistrement du gestionnaire d'événements natif avec le travail qu'une bibliothèque comme jQuery fera est probablement une très mauvaise idée à moins que vous ne sachiez sérieusement ce que vous faites.

Il y avait ne question posée presque exactement comme celle-ci il y a peu de temps aujourd'hui.

22
Pointy

Regardez la version addEventListener:

document.getElementById('outer').addEventListener('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

Cela fonctionne très bien car le troisième argument est useCapture, qui spécifie si la phase de capture de l'événement doit être utilisée ou non.

Lorsque vous passez à la version jQuery:

$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

Je pense que ce qui se passe est le troisième argument simplement remplace votre fonction de gestionnaire d'événements et fait que le gestionnaire d'événements ne fait que return false; ce qui n'est clairement pas ce qui doit arriver.

De la docs jQuery (emphase ajoutée):

Une fonction à exécuter lorsque l'événement est déclenché. La valeur false est également autorisée comme raccourci pour une fonction qui renvoie simplement false .

Supprimez l'argument false et la version jQuery fonctionnera également correctement:

$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
});

Notez que alert devrait apparaître, donc l'approche addEventListener fonctionne correctement. Voir la réponse de @ Pointy pour savoir pourquoi.

12
James Allardice