: javascript

Evènements et instances

Les fonctions liées à des éléments du DOM sont appelées lors du déclenchement d'un évènement avec un contexte d'instance qui représente l'élément du DOM. C'est souvent pratique, mais si l'on a besoin de gérer d'autre informations c'est parfois réducteur.

Voici un exemple d'objet qui sert à compter le nombres de clics sur un élément DOM et qui affiche un message après 10 clics.

function Compteur(element) {
  this.counter =  10; // variable pour compter
  addEvent(element, 'click', this.count); // attache l'évènement
}

Compteur.prototype.count = function() {
  this.counter--; // diminue counter de 1
  if(this.counter==0) alert('Message');
}

// crée un compteur pour un élement
new Compteur( document.getElementById('element1') );
// crée un autre compteur pour un autre élément
new Compteur( document.getElementById('element2') );

Dans cet exemple il y a deux instances de l'objet Compteur. Le problème se situe au niveau de la fonction count, celle-ci est attachée au gestionnaire d'évènements et sera appelée quand on clic sur l'élément DOM lié.

this fait référence à l'élément du DOM et non à l'instance de l'objet Compteur. Ainsi this.counter fait référence à la propriété counter de l'élément du DOM. Cette propriété n'existe pas dans un élément DOMOn aurrait le droit de la créer en étendant le DOM, mais c'est une autre histoire.

apply et call permettent de palier à ce problème. On attachera une fonction anonyme au gestionnaire d'évènement qui s'occupera de la liaison (binding).

function Compteur(element) {
  this.counter =  10; // variable pour compter
  var instance = this; // crée une 'closure'
  addEvent(element, 'click', function() {
    instance.count.apply(instance);
  });
}
Editer