Presque tout ce que vous faites en JavaScript est supposé commencer lorsque quelque chose se passe: l'utilisateur clique sur un bouton, passe au-dessus d'un menu, appuie sur une touche, vous voyez l'idée. C'est assez simple à faire avec des bibliothèques comme jQuery, mais savez-vous comment câbler des événements en JavaScript brut? Aujourd'hui, je vais vous apprendre que!
La gestion d'événements JavaScript n'est pas sorcière. Bien sûr, il existe des différences de navigateur (qu'attendiez-vous?), Mais une fois que vous avez compris et créé vos propres fonctions d'assistance, même sur le terrain, vous serez heureux de le savoir. Même si vous envisagez toujours d'utiliser une bibliothèque pour ce genre de choses, il est bon de savoir ce qui se passe sous la surface. Et c'est parti.
La gestion des événements la plus élémentaire en JavaScript est la gestion des événements de niveau 0. C'est assez simple: assignez simplement votre fonction à la propriété event de l'élément. Observer:
var element = document.getElementById ('myElement'); element.onclick = function () alert ('votre fonction ici'); ;
Une fois que j'ai l'élément, je règle le sur clic
propriété égale à une fonction. Maintenant, quand élément
est cliqué, cette fonction s'exécutera et nous verrons un message d'alerte.
Mais comment j'ai su utiliser sur clic
? Vous pouvez obtenir une liste des événements disponibles sur Wikipedia. L'avantage de la méthode de niveau 0 est qu'elle est prise en charge par tous les navigateurs largement utilisés aujourd'hui. L'inconvénient est que vous ne pouvez enregistrer chaque événement qu'une seule fois avec chaque élément. Donc, cela ne provoquera qu'une alerte:
element.onclick = function () alert ('fonction 1'); ; element.onclick = function () alert ('Je remplace la fonction 1');
Seule la deuxième fonction sera exécutée lorsque l'utilisateur cliquera sur l'élément, car nous avons réaffecté la propriété onclick. Pour supprimer un gestionnaire d'événement, nous pouvons simplement le définir sur null.
element.onclick = null;
Bien qu'il ne propose que des fonctionnalités de base, la prise en charge cohérente sur tous les navigateurs fait de la gestion d'événements de niveau 0 une option valable pour les projets super simples.
Maintenant que vous abordez les événements JavaScript, examinons deux aspects importants avant de passer à de meilleures techniques: l’objet événement et le ce
mot-clé. Lorsqu'un événement est exécuté, vous voudrez peut-être connaître de nombreuses informations sur l'événement: quelle touche a été enfoncée? quel élément a été cliqué? l'utilisateur at-il cliqué avec le bouton gauche, droit ou central? Toutes ces données et plus sont stockées dans un objet événement. Pour tous les navigateurs sauf Internet Explorer, vous pouvez accéder à cet objet en le transmettant en tant que paramètre à la fonction de traitement. Dans IE, vous pouvez l'obtenir à partir de la variable globale window.event
. Ce n'est pas difficile de résoudre cette différence.
fonction myFunction (evt) evt = evt || window.event; / *… * / Element.onclick = myFunction;
ma fonction
prend le paramètre événement pour tous les bons navigateurs, et nous le réaffectons à window.event
si evt
n'existe pas. Nous verrons un peu plus tard quelques propriétés de l'objet événement.
le ce
le travail clé est important dans les fonctions de gestion des événements; il fait référence à l'élément qui a reçu l'événement.
element.onclick = function () this.style.backgroundColor = 'red'; // identique à element.style.backgroundColor = 'red';
Malheureusement, dans Internet Explorer, ce
ne fait pas référence à l'élément acted; il fait référence à l'objet window. C'est inutile, mais nous étudierons un moyen d'y remédier dans un instant..
Le traitement des événements de niveau 2 est la spécification W3C pour les événements DOM. C'est assez simple, en fait.
element.addEventListener ('mouseover', myFunction, false);
La méthode s'appelle addEventListener
. Le premier paramètre est le type d'événement que nous voulons écouter. Généralement, il s'agit du même nom que les événements de niveau 0, sans le préfixe "on". Le deuxième paramètre est soit un nom de fonction, soit la fonction elle-même. Le paramètre final détermine si nous capturons ou non; nous en discuterons dans un instant.
L’un des gros avantages de l’utilisation de addEventListener
est que nous pouvons maintenant affecter plusieurs événements pour un seul événement sur un seul élément:
element.addEventListener ('dblclick', logSuccessToConsole, false); element.addEventListener ('dblclick', function () console.log ('cette fonction ne supprime pas le premier.');, false);
Pour supprimer ces gestionnaires, utilisez la fonction removeEventListener
. Donc, pour supprimer la fonction que nous avons ajoutée ci-dessus, procédez comme suit:
element.removeEventListener ('dblclick', logSuccessToConsole, false);
Le dernier paramètre de addEventListner
et removeEventListener
est un booléen qui définit si nous déclenchons l'événement au stade de la capture ou du bullage. Voici ce que cela signifie:
Lorsque vous cliquez sur un élément, vous cliquez également sur chacun de ses éléments ancêtres..
Enregistrer le travail
Si je clique sur le span # save
, J'ai aussi cliqué barre d'outils div #
, div # wrapper
, et corps
. Ainsi, si l'un de ces éléments dispose d'écouteurs d'événements à l'écoute des clics, leurs fonctions respectives seront appelées. Mais dans quel ordre devraient-ils être appelés? C'est ce que le dernier paramètre décide. Dans la spécification W3C, notre événement clic commencerait à la corps
et déplacez-vous dans la chaîne jusqu'à ce qu'il atteigne la span # save
; c'est l'étape de la capture. Ensuite, ça va du span # save
remonter au corps
; c'est la phase bouillonnante. Cela est facile à retenir, car les bulles flottent vers le haut. Tous les événements ne bouillonnent pas; ce tableau Wikipedia vous dira ceux qui font et ceux qui ne le font pas.
Donc, si le paramètre de capture est défini sur vrai
, l'événement sera déclenché en descendant; si c'est réglé sur faux
, il sera déclenché en montant.
Vous avez peut-être remarqué que, jusqu'à présent, tous mes exemples ont défini la capture sur false, de sorte que l'événement est déclenché à l'étape de la propagation. En effet, Internet Explorer ne comporte pas de phase de capture. Dans IE, seuls les événements en bulle.
IE a sa propre façon de travailler avec les événements. Il utilise attachEvent
.
element.attachEvent ('onclick', runThisFunction);
Puisque les événements IE ne font que bouillonner, vous n’avez pas besoin de la troisième variable. Les deux premiers sont les mêmes qu'avec addEventListener
, avec la grande exception que IE nécessite ce préfixe 'on' pour le type d'événement. Bien entendu, vous pouvez affecter plusieurs événements du même type à un élément individuel avec ce modèle. Pour supprimer des événements, utilisez detachEvent
.
element.detachEvent ('onclick', runThisFunction);
Et si vos éléments ne veulent pas que leurs parents découvrent leurs événements? Ce n'est pas difficile à cacher. Dans IE, vous utilisez le cancelBubble
propriété sur l'objet événement transmis à la fonction appelée. Pour le reste, vous pouvez utiliser le stopPropogation
méthode, également sur l'objet événement.
e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation ();
le stopPropogation
méthode va également arrêter les événements dans leurs traces au cours de la phase de capture.
Je serais prêt à parier que la plupart des propriétés de l'objet événement resteront inutilisées, mais vous en trouverez quelques unes que vous trouvez précieuses. Regardons ces quelques.
le cible
La propriété est l'élément le plus profond sur lequel vous avez cliqué. Dans l'image ci-dessus, vous pouvez voir que j'ai cliqué bouton h1 #
. Dans IE, cette propriété s'appelle srcElement
; pour obtenir à cette propriété, faire quelque chose comme ça:
var target = e.target || e.srcElement;
le currentTarget
propriété est l'élément qui a l'événement en ce moment. Dans cette capture d'écran, le currentTarget
est div # wrapper
. Cela signifie que j'ai cliqué bouton h1 #
, mais l'objet événement a été connecté à la console dans la fonction appelée par le div # wrapper
Auditeur de l'événement.
Mais cela vous jettera pour une boucle: IE ne possède pas de propriété currentTarget, ou quoi que ce soit du genre. Rappelant le fait que IE ne laisse même pas ce
égal à l'élément déclenchant l'événement, cela signifie que nous n'avons aucun moyen de récupérer l'élément qui a déclenché l'événement lorsque le fichier est en train de bouillonner (ce qui signifie qu'un descendant de l'élément a été cliqué). Confus? Peut-être qu'un exemple aidera: si, dans Internet Explorer, nous avons ce code HTML…
Bouton
… Et ce gestionnaire d'événements…
var par = document.getElementById ('parent'); parent.attachEvent ('onclick', quelque chose);
… Puis, quand on clique sur le bouton span # enfant
et l'événement bouillonne jusqu'à div # parent
, nous n'avons aucun moyen de l'intérieur de la fonction faire quelque chose
pour obtenir l'élément (dans ce cas, div # parent
) l'événement a été déclenché le.
Vous trouverez d'autres propriétés sur l'objet événement que vous trouverez utiles, selon le cas. Sur un événement de clavier (raccourci clavier, touche enfoncée, pression au clavier), vous serez le code clé
et le charCode
. Vous serez en mesure de savoir si l'utilisateur a appuyé sur les touches alt, shift ou ctrl (cmd) tout en appuyant / cliquant. Explorez les objets d'événements de différents événements et voyez avec quoi vous devez travailler!
Nous avons rencontré deux problèmes principaux dans notre étude des événements à ce jour.
currentTarget
la propriété, et la ce
objet référence l'objet window.Pour résoudre ces problèmes, construisons deux fonctions prenant en charge plusieurs navigateurs, une pour connecter des événements et une pour les supprimer..
Nous allons commencer avec ajouter un évènement
; voici le premier tour:
var addEvent = function (élément, type, fn) if (élément.attachEvent) élément.attachEvent ('sur' + type, fn); else element.addEventListener (type, fn, false);
J'attribue une fonction anonyme à la variable ajouter un évènement
pour des raisons que vous verrez dans une minute. Tout ce que nous avons à faire est de vérifier si l'élément possède le attachEvent
méthode. Si c'est le cas, nous sommes dans IE et nous utiliserons cette méthode. Sinon, nous pouvons utiliser addEventListener
.
Cependant, cela ne résout pas le fait que nous n'avons aucun moyen d'accéder à l'élément parent de l'événement dans IE. Pour ce faire, nous allons faire de la fonction un attribut sur l'élément; de cette façon, il est perçu comme une méthode de l'élément, et ce
sera égal à l'élément. Oui, je sais, brillant, n'est-ce pas? Eh bien, je ne peux prendre aucun crédit: cette idée provient d'un article de blog de John Resig.
var addEvent = fonction (élément, type, fn) if (élément.attachEvent) élément ['e' + type + fn] = fn; element [type + fn] = function () element ['e' + type + fn] (window.event); element.attachEvent ('on' + type, element [type + fn]); else element.addEventListener (type, fn, false);
La première ligne supplémentaire (élément ['e' + type + fn] = fn;
) fait de la fonction une méthode de l'élément, de sorte que ce
sera maintenant égal à l'élément. La deuxième ligne est une fonction qui exécute la méthode en passant à l’objet window.event. Cela vous évite d'avoir à vérifier le paramètre d'objet d'événement dans votre fonction. Enfin, notez que nous avons changé le paramètre de fonction dans attachEvent
méthode pour élément [type + fn]
.
Cela résout nos deux problèmes. Nous pouvons maintenant utiliser notre ajouter un évènement
fonctionner dans tous les navigateurs avec une expérience similaire autant que possible. Mais il y a un peu d'optimisation que nous aimerions faire.
Notez que chaque fois notre ajouter un évènement
fonction est appelée, elle vérifie la attachEvent
méthode. Il n'y a aucune raison pour que nous vérifiions cela plus d'une fois, quel que soit le nombre d'événements que nous souhaitons enregistrer. Nous pouvons utiliser une astuce astucieuse qui nous permettra de ré-écrire ajouter un évènement
.
var addEvent = fonction (el, type, fn) if (el.attachEvent) addEvent = fonction (el, type, fn) el ['e' + type + fn] = fn; el [type + fn] = fonction () el ['e' + type + fn] (window.event); ; el.attachEvent ('on' + type, el [type + fn]); else addEvent = fonction (el, type, fn) el.addEventListener (type, fn, false); addEvent (el, type, fn);
Maintenant, si le ajouter un évènement
méthode est trouvée, nous ré-écrivons ajouter un évènement
inclure uniquement les éléments IE; sinon, nous inclurons simplement les bonnes parties du navigateur.
Notre removeEvent
la fonction sera très similaire:
var removeEvent = function (élément, type, fn) if (element.detachEvent) removeEvent = fonction (élément, type, fn) element.detachEvent ('on' + type, el [type + fn]); element [type + fn] = null; else removeEvent = function (élément, type, fn) élément.removeEventListener (type, fn, false); removeEvent (element, type, fn);
C'est tout pour nos fonctions d'événement multi-navigateurs. Il y a une chose que je n'aime pas chez eux, cependant: les fonctions ne sont pas des méthodes des éléments; au lieu de cela, l'élément est un paramètre. Je sais que c'est juste une question de style, mais j'aime bien
btn.addEvent ('click', doThis);
mieux que
addEvent (btn, 'click', doThis);
Nous pourrions faire cela en enveloppant nos fonctions dans ceci:
var E = Element.prototype; E.addEvent = fonction (type, fn) addEvent (this, type, fn); E.removeEvent = function (type, fn) removeEvent (this, type, fn);
Cela fonctionnera dans tous les navigateurs modernes, ainsi que dans IE8; IE7 et IE6 s'étouffent Élément
. Cela dépend de votre public. à prendre ou a laisser!
Maintenant que vous savez tout sur les événements JavaScript, ne vous précipitez pas et ne remplissez pas votre prochain projet avec des écouteurs d'événements. Si de nombreux éléments répondent au même type d’événement (par exemple, cliquez sur), il est plus sage de tirer parti du bouillonnement. Vous pouvez simplement ajouter un écouteur d'événement à un élément ancêtre, même le corps, et utiliser la propriété target / srcElement sur l'objet événement pour déterminer quel élément plus profond a été cliqué. Ceci s'appelle la délégation d'événement. Voici un exemple inutile:
Voici du HTML:
Nous pouvons utiliser la délégation d'événements pour gérer les clics sur chacun li
:
fonction de navigation (e) var el = e.target || e.srcElement; switch (el.id) case 'home': alert ('rentrer à la maison'); Pause; case 'portfolio': alert ('Découvrez mes produits'); Pause; case 'about': alert ('tous ces détails dégoûtants'); Pause; cas 'contact': alerte ('Je vous flatte de parler'); Pause; défaut: alert ('comment êtes-vous arrivé ici?'); var nav = document.getElementById ('nav'); addEvent (nav, 'click', navigation);
Nous utilisons une instruction switch / case pour examiner l'id de l'élément cliqué plus profond. Ensuite, nous faisons quelque chose en conséquence.
Vous pouvez donc maintenant utiliser les événements JavaScript avec les meilleurs. Amusez-vous et posez des questions dans les commentaires.!