Je suis tombé sur un bogue Javascript dans Safari 2.0.4 sur Mac.
J’étais en train de coder un pré-chargement d’image, comme ceux qu’on trouve dans des scripts comme Thickbox et Lightbox. En fait, je me suis inspiré de celui de Thickbox, qui, globalement, n’est qu’en fait que quelques lignes
imgPreloader = new Image();
imgPreloader.onload = function() {
// Code à exécuter lorsque l'image est complètement chargée
}
imgPreloader.src = "/img/test.jpg";
Plutôt simple, non? À date, oui. Cependant, lorsque l’image était chargée, je devais aller récupérer la taille de cette image. Pour récupérer mon objet Image, j’utilise donc la variable this, puisque je suis dans une de ses méthodes.
imgPreloader = new Image();
imgPreloader.onload = function() {
alert("Largeur: " + this.width);
}
imgPreloader.src = "/img/test.jpg";
Ça marche, et c’est normal que ça marche. Cependant Safari Mac, lui, n’affecte pas la même valeur à this — pour lui, this est une référence à window et non à imgPreloader! Incompréhensible!
Peut-être que c’est moi qui a mal compris quelque chose, mais il me semble qu’en Javascript (et dans la plupart des langages de programmation orientée objet) lorsqu’on appelle une méthode d’un objet, la variable this dans cette méthode est une référence à l’objet en soi, non?
Bref, il est facile de contourner le problème, une fois que l’on comprend ce qui clochait :
imgPreloader = new Image();
imgPreloader.onload = function() {
alert("Largeur: " + imgPreloader.width);
}
imgPreloader.src = "/img/test.jpg";
J’utilise donc la variable imgPreloader dans l’objet imgPreloader pour avoir une référence à lui-même… vivement Safari 3!
Des fois il faut ce méfier de
thisen Javascript, qui ne fonctionne pas tout à fait comme dans bien d’autre langages. Mais dans ce cas, je crois bien que Safari est dans l’erreur.Michel Fortin (28 septembre 2007 à 16:56 EST)