11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'ai une classe javascript gérant des infobulles (des divs d'aide qui s'affichent au survol de la souris)
Elles sont gérées par une classe Infobulle et une classe IfbManager qui s'occupe juste de vérifier qu'on n'a pas plusieurs Ifb (je vais utiliser cette abréviation pour "infobulle" si ça ne vous embête pas) ouvertes en même temps.

Tout fonctionnait très bien jusqu'à ce que j'ajoute une fonctionnalité les rendant "lockables"
C'est à dire qu'elles disposent maintenant d'un petit bouton qui fait qu'elles ne s'effacent plus à la fin du survol.

A ce moment j'ai ce code qui est appelé (version épurée):


// Méthode lock: Convertit en infobulle fixe
Infobulle.prototype.lock = function() {
	// Active le bouton de fermeture
	oIfb = this;
	this.html_c.onclick = function(event) {alert('fermeture de ' + oIfb.id); oIfb.hide();}
}


Note: this.html_c est un <a> (lors que je crée le contenu de la popup je garde la référence sur le bouton de fermeture)

Maintenant je crée une première ifb lockée d'id "ifb1"
Puis une seconde d'ID "ifb2"

Jusque là tout va bien.

Ensuite je tente de fermer ifb1... c'est ifb2 qui se ferme. (et il m'affiche "ifb2")

En fait, ce qui se passe, c'est que le gestionnaire d'événements ajouté dynamiquement au sein de la classe se rattache à la dernière instance créée de la classe, et non à l'instance au sein de laquelle il a été appelé.
C'est un peu comme si j'appelais un membre statique, sauf que c'est un "this" qui par définition ne peut pas être statique...

Bref, ça n'a pas de sens.

C'est la première fois que je m'attaque à du javascript "objet" (enfin, prétendu tel) donc un truc m'a sans doute échappé...

Déjà c'est assez étrange, je suis obligé d'utiliser une combine, c'est à dire écrire le code sur 2 lignes. En effet le code suivant plante lamentablement:

this.html_c.onclick = function(event) {this.hide();}

Si quelqu'un a compris et peut m'expliquer ce qui se passe...
Suite de ma recherche, j'ai trouvé cet article sur une autre forum:

http://javascript.developpez.com/faq/?page=DOM#dom.onclick.dynamique

Ca ressemble pas mal à mon problème.

Cela dit ça me semblerait louche. Ou alors c'est vraiment que javascript est bizarre au niveau de la gestion de la portée de ses variables et surtout de sa gestion de références d'objet...

En tout cas si c'est la même chose, ça veut dire que je dois revoir toute ma conception.

Bref! Si quelqu'un peut m'expliquer ce que fait précisément javascript dans mon cas...
Bonjour,

Je te conseille la lecture de cet article : Scope in JavaScript

Pour ton problème :
a écrit :
Déjà c'est assez étrange, je suis obligé d'utiliser une combine, c'est à dire écrire le code sur 2 lignes. En effet le code suivant plante lamentablement:
this.html_c.onclick = function(event) {this.hide();}

c'est normal, le this à l'intérieur de ta fonction anonyme se réfère au DOM Element 'this.html_c'



a écrit :
Infobulle.prototype.lock = function() {

	// Active le bouton de fermeture

	oIfb = this;

	this.html_c.onclick = function(event) {alert('fermeture de ' + oIfb.id); oIfb.hide();}

}


Ensuite je tente de fermer ifb1... c'est ifb2 qui se ferme. (et il m'affiche "ifb2")


oIfb est déclarée en tant que variable globale.

ça devrait être mieux ainsi:

var oIfb = this;


a+

dunjl
Merci pour ton aide.

J'ai lu pas mal d'articles entre temps et j'ai un peu mieux compris. Pour mon problème j'ai fait autrement en travaillant avec les indices de mon tableau global contenant l'ensemble de mes Infobulles. C'est moins beau car mes objets ne sont plus autonomes mais en travaillant avec des valeurs je suis moins perturbé par le comportement de javascript qu'avec des références d'objet.

J'ai du mal avec le javascript objet mais ça va venir. C'est assez particulier tout de même comme langage à ce niveau Smiley confus