Pages

Les évenements en JS



Nous avons déjà vu les pièges à éviter lors de l'écriture de la gestion d'événements.
  • perte du this
  • passage de paramètres. 
Voici un exemple des problèmes de passage de paramètres :
Voici donc comment écrire la gestion d'événements en Javascript.

Pré-requis : La compréhension fait appel à la notion de closure.

Pour exemple, nous simulons un comportement basique (code jquery)
$( "p" ).on( "click", function() {
  $(this).toggleClass("selected");
});

En JavaScript
for (var i = 0; i < ps.length; i++) {
  ps[i].addEventListener("click", function(){  
    this.classList.toggle('selected');  
  }, true);
}

Allons plus loin.Nous voulons manipuler l'objet cliqué et connaître son indice.

Voici le code en JS (code que nous allons rendre beaucoup plus compréhensif par la suite)
(function(){
var zone = document.body.querySelector("div");
var zonePs = zone.querySelectorAll('p','div'); 

for (var i = 0; i < zonePs.length; i++) {
  zonePs[i].addEventListener("click", 
                             (function(index, para){ 
                                  return function(e) { 
                                     console.log("nb =" + index);
                                     para.classList.toggle('selected'); 
                                  };
                              })(i,zonePs[i]), 
                             true);
}
})();

Nous allons décomposer le code en trois étapes

  1. sélection
  2. closure
  3. action
Etape de sélection

var zone = document.body.querySelector("div");
var zonePs = zone.querySelectorAll('p'); 

Ecriture de la closure

L'idée est simple, la closure va permettre de rendre accessibles à une fonction (portée des variables) des paramètres. 

  • Les paramètres sont ici le paragraphe et son numéro dans la liste des paragraphe à traiter.
  •  La fonction est l'action a réaliser lors du clique.

Par défaut seul l'événement est disponible dans la fonction action, la closure rajoute des variables supplémentaires (par exemple : le numéro de paragraphe et l'identifiant).

Sans closure seul l'événement est accessible à l'action
Grace à la closure, d'autres paramètres sont disponibles


for (var i = 0; i < zonePs.length; i++) {
  zonePs[i].addEventListener("click", 
                             closure(i, zonePs[i]), 
                             true);

}

Remarquez que la fonction closure est immédiatement exécutée.


function closure(index, para) {
   //closure index et para dispo pour la fonction suivante
        console.log("closure index = "+ index);
        console.log("closure type = "+ para.nodeName);
  
  //déclaration d'une fonction anonyme actionnée lors du clic
        return function(e) { 
          console.log(e.type + " index = "+ index);
          console.log(e.type + " typeNode " + para.nodeName);
          action(para); 
        };

}

Ainsi, lors de l'exécution de la boucle, on exécute deux fois la fonction closure.


Exemple d'application :

Remarque

L'arrivée de Array.from et de la délégation permet de simplifier le code et diminue le nombre d'événement à écrire.