2009-12-08 4 views
0

J'ai un constructeur avec ces méthodes:Firebug: "événement n'est pas défini"

  
function getMouseXY(event){ 
     var x = event.clientX - this.offsetLeft; 
     var y = event.clientY - this.offsetTop; 
    return [x,y]; 
} 

function alertx(){ 
    var c = this.getMouseXY(event); 
    alert(c[0]); 
} 

Dans le code HTML i assigne la fonction alertx à un événement de toile HTML5 de mouseup:

 
document.getElementById('cbackground').addEventListener('mouseup', object.alertx, false); 

Quel est le résultat attendu? Le fait de cliquer sur la toile montre la position X de la souris, à la place je n'obtiens rien. Une exploration plus poussée avec Firebug m'obtient l'erreur "l'événement n'est pas défini". Je ne sais pas comment éviter ça! Des conseils? Merci!

Répondre

3

Voyons quelques questions:

  1. Le alertx() ne reçoit pas un argument event.
  2. Dans cette fonction, vous appelez getMouseXY en utilisant this. Les mots-clés à ce moment-là, se réfèrent à l'élément qui a déclenché l'événement.
  3. Vous liez le gestionnaire d'événements à une variable inconnue object.

Je pense que vous voulez faire quelque chose comme ceci:

function getMouseXY(event){ 
     var x = event.clientX - this.offsetLeft, // notice, 'this' is used 
      y = event.clientY - this.offsetTop; 

    return [x,y]; 
} 

function alertx(event){ 
    var c = getMouseXY.call(this, event); // set the element as 'this' 
    alert(c[0]); 
} 

Et si vous avez une fonction constructeur, et les fonctions ci-dessus sont des méthodes d'instance, vous pouvez faire quelque chose comme ceci:

function MyObject() { // constructor 
} 

MyObject.prototype.getMouseXY = function (event) { 
     var x = event.clientX - this.offsetLeft, 
      y = event.clientY - this.offsetTop; 

    return [x,y]; 
}; 

MyObject.prototype.alertx = function (event, element) { 
    var c = this.getMouseXY.call(element, event); 
    alert(c[0]); 
} 

Lorsque vous liez l'événement, vous pouvez ajouter une fonction anonyme, pour faire respecter le contexte:

var object = new MyObject(); 
document.getElementById('cbackground').addEventListener('mouseup', function (e) { 
    object.alertx(e, this); // alertx will be called with the correct 'this' 
}, false); 

Edit: En réponse à votre commentaire, il vous suffit de savoir comment le contexte (le mot-clé this) est défini implicitement:

Lorsque vous appelez une méthode d'instance comme:

obj.method(); 

le mot-clé dans la thismethod, se référeront à obj.

La même chose se produit lorsque vous appelez les variables globales, puisqu'elles sont membres de l'objet global (window dans les scripts de navigateur):

globalFunction(); 

équivaut à:

window.globalFunction(); 

Et le contexte à l'intérieur de cette fonction sera l'objet global lui-même (window).

Un autre cas se produit lorsque vous utilisez l'opérateur new:

var instance = new MyConstructor(); 

Le mot-clé this dans ce cas, sera un nouvel objet, créé par l'utilisation de l'opérateur new.

Lorsque vous utilisez une fonction comme un gestionnaire d'événements, le mot-clé this fera référence au tha élément a déclenché l'événement:

document.getElementById('myId').onclick = obj.myFunction; 

Dans ce cas myFunction est une méthode d'instance de obj, mais le mot-clé this le seront reportez-vous à l'élément DOM sur lequel vous avez cliqué.

Et enfin, comme vous l'avez vu dans mon code, le contexte peut être défini explicitement par l'utilisation de call ou apply.

+0

Incroyable, merci! Le .call a résolu le problème, je vais en lire plus, j'ai un constructeur, et ces fonctions sont des méthodes, quel est l'intérêt du prototypage dans ce cas? –

+0

J'ai modifié le code pour le rendre conforme au modèle de prototypage (constructeur, méthode d'addition en les prototypant, votre deuxième cas) et j'obtiens un "this.getmouseXY is undefined" –

+0

@Gabriel: Pourriez-vous poster le code? , dans votre question ou sur http://jsbin.com? – CMS

0

Sur var c = this.getMouseXY(event); vous passez une variable non affectée (événement) à la fonction, ce qui explique pourquoi il est en train de sauter. Peut-être avez-vous oublié d'ajouter l'argument à alertx()?

+0

Je viens d'utiliser l'événement pour que les fonctions clientY et clientX fonctionnent, pas parce que je le voulais ... :(Je ne sais pas comment le gérer dans alertx –

0

Dans la fonction alertx, l'événement n'est jamais initialisé. Si vous utilisez function alertx(event), cela devrait fonctionner.

+0

Cela fait une erreur, this.getMouseXY n'est pas une fonction ... –